summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/body_layer.zig2
-rw-r--r--src/ninep/pane.zig13
-rw-r--r--src/tagline.zig34
3 files changed, 35 insertions, 14 deletions
diff --git a/src/body_layer.zig b/src/body_layer.zig
index 04c84b62..ab8a888a 100644
--- a/src/body_layer.zig
+++ b/src/body_layer.zig
@@ -685,7 +685,7 @@ fn tagTintRange(pane: *const Pane, tag: []const u8, prefix_len: usize) ?struct {
if (pane.prompt == .name) pane.input.own orelse file.path else file.path
else if (pane.image) |state| blk: {
// Image tags put renderer controls before the path.
- start = prefix_len -| state.path.len;
+ start = std.mem.lastIndexOf(u8, tag[0..prefix_len], state.path) orelse return null;
break :blk state.path;
} else if (comptime pdf_enabled) blk: {
break :blk if (pane.pdf) |state| state.path else return null;
diff --git a/src/ninep/pane.zig b/src/ninep/pane.zig
index 8e827fba..245e0bb4 100644
--- a/src/ninep/pane.zig
+++ b/src/ninep/pane.zig
@@ -893,6 +893,19 @@ test "truncating the tag clears its editable tail" {
try testing.expectEqual(Status.ok, cleared.reply.status);
try testing.expectEqualStrings("", pane.tag.own.?);
try testing.expect(std.mem.indexOf(u8, rd(p, tag, 0, 4096).bytes, " Mine") == null);
+
+ // Written back without a leading space, the text still stands apart
+ // from the path: the computed prefix brings the separator, so Look and
+ // Exec find `Get`, not `test.txtGet`.
+ _ = wr(p, tag, "Get");
+ try testing.expectEqualStrings("Get", pane.tag.own.?);
+ const whole = rd(p, tag, 0, 4096).bytes;
+ try testing.expectEqualStrings("/test.txt Get", whole);
+ const word = config.wordBounds(whole, whole.len - "Get".len);
+ try testing.expectEqualStrings("Get", whole[word.lo..word.hi]);
+ // and the keyboard's first column of the text is the G
+ const at = tagline.tagOffsetAt(p, pane, 0, "/test.txt ".len).?;
+ try testing.expectEqual(@as(usize, 0), at.col);
}
test "name reads the file name and writing it promotes a scratch without touching its body" {
diff --git a/src/tagline.zig b/src/tagline.zig
index a918689b..8bd8000a 100644
--- a/src/tagline.zig
+++ b/src/tagline.zig
@@ -104,19 +104,27 @@ pub fn revealHeader(p: *Pardes) void {
pub fn tagPrefix(p: *Pardes, pane: *Pane) ![]u8 {
const arena = p.scratch.allocator();
- if (comptime pdf_enabled) if (pane.pdf) |pv| return std.fmt.allocPrint(
- arena,
- "{s} [{d}/{d}]",
- .{ pv.path, pv.page + 1, pv.page_count },
- );
- if (pane.image) |*state| return panes.Image.tagPrefix(arena, state);
- if (pane.file) |f| {
- const name = if (pane.prompt == .name) pane.input.own orelse f.path else f.path;
- if (panes.Output.fileTraits(f.output).saves and f.revision != f.saved_revision)
- return std.fmt.allocPrint(arena, "{s}{s}", .{ name, dirty_marker });
- return arena.dupe(u8, name);
- }
- return arena.dupe(u8, pane.cwdSlice());
+ const prefix = prefix: {
+ if (comptime pdf_enabled) if (pane.pdf) |pv|
+ break :prefix try std.fmt.allocPrint(arena, "{s} [{d}/{d}]", .{ pv.path, pv.page + 1, pv.page_count });
+ if (pane.image) |*state| break :prefix try panes.Image.tagPrefix(arena, state);
+ if (pane.file) |f| {
+ const name = if (pane.prompt == .name) pane.input.own orelse f.path else f.path;
+ if (panes.Output.fileTraits(f.output).saves and f.revision != f.saved_revision)
+ break :prefix try std.fmt.allocPrint(arena, "{s}{s}", .{ name, dirty_marker });
+ break :prefix name;
+ }
+ break :prefix pane.cwdSlice();
+ };
+ // The space between the prefix and the tag's own text is the text's
+ // (every default starts with one), but the prefix is computed, so it
+ // cannot trust the text to keep it: with it deleted, Look and Exec
+ // would see the path and the first word as one. The prefix brings its
+ // own then.
+ const tail = curTail(pane);
+ if (tail.len > 0 and std.mem.indexOfScalar(u8, " \t\n", tail[0]) == null)
+ return std.fmt.allocPrint(arena, "{s} ", .{prefix});
+ return arena.dupe(u8, prefix);
}
/// The tag's own text: what the user made of it, or until then the