summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-28 19:41:44 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:15 -0300
commite0b3f11f008e54174d5169147b8cf5dac56e915a (patch)
tree888e1cfb21a381b599ae59f1b1942572aba54fa9 /src
parentfb87946e09bf33c0fe663ccba6db14a63e7cfda4 (diff)
downloadpardes-e0b3f11f008e54174d5169147b8cf5dac56e915a.tar.gz
pardes-e0b3f11f008e54174d5169147b8cf5dac56e915a.zip
A tag no longer marks an unsaved file with *: the grip shows it
The grip button now shows a pane's unsaved text in every state, as acme's modbutton does, and acme's tag has no asterisk. The computed prefix is the name alone, so tag reads, event offsets that count the path and the tag's text lose the " *". dirty, index's flag and the refuse-once guards are unchanged; a dump from before still restores its tags past the old mark. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/pardes.zig28
-rw-r--r--src/tagline.zig11
2 files changed, 10 insertions, 29 deletions
diff --git a/src/pardes.zig b/src/pardes.zig
index 7cdd8461..a232c9c6 100644
--- a/src/pardes.zig
+++ b/src/pardes.zig
@@ -1251,37 +1251,19 @@ test "pane defaults keep creation of scratch panes in column tags" {
try std.testing.expectEqualStrings(tagline.file_pane_tail, tagline.curTail(file));
}
-test "an unsaved file marker sits between its path and builtins until Save" {
+test "an unsaved file's tag is its name alone: the grip, not a mark, says it is unsaved" {
const gpa = std.testing.allocator;
const p = try Pardes.init(gpa, .{ .tty_only = true, .cols = 100, .rows = 30 });
defer p.deinit();
while (p.nextEffect()) |_| {}
const pane = try p.setTestFile("before\n");
-
const clean = try tagline.tagText(p, p.scratch.allocator(), pane);
- try std.testing.expect(std.mem.indexOf(u8, clean, "/test.txt *") == null);
-
panes.File.setContent(p, &pane.file.?, try gpa.dupe(u8, "after\n"));
const dirty = try tagline.tagText(p, p.scratch.allocator(), pane);
- const marker_at = std.mem.indexOf(u8, dirty, "/test.txt *") orelse return error.MissingDirtyMarker;
- const save_at = std.mem.indexOf(u8, dirty, "Save") orelse return error.MissingSaveBuiltin;
- try std.testing.expect(marker_at < save_at);
-
- try std.testing.expect(p.executeBuiltinLine(0, "Save"));
- while (p.nextEffect()) |effect| p.perform(effect);
- const saved = try tagline.tagText(p, p.scratch.allocator(), pane);
- try std.testing.expect(std.mem.indexOf(u8, saved, "/test.txt *") == null);
-
- panes.File.changed(p, 0, "external\n");
- const reloaded = try tagline.tagText(p, p.scratch.allocator(), pane);
- try std.testing.expect(std.mem.indexOf(u8, reloaded, "/test.txt *") == null);
-
- // A generated output is file-shaped and Save can write it to a path, but
- // there is no file of its own for it to be dirty against.
- pane.file.?.output = .{ .from = .search };
- panes.File.setContent(p, &pane.file.?, try gpa.dupe(u8, "result\n"));
- const output = try tagline.tagText(p, p.scratch.allocator(), pane);
- try std.testing.expect(std.mem.indexOf(u8, output, "/test.txt *") == null);
+ try std.testing.expectEqualStrings(clean, dirty);
+ try std.testing.expect(std.mem.indexOf(u8, dirty, " *") == null);
+ // The dirty file and index's flag still say it.
+ try std.testing.expect(ctlfs.pane.dirtyOf(pane));
}
test "unknown Exec from a document runs as a command pane in its directory, typed into no terminal" {
diff --git a/src/tagline.zig b/src/tagline.zig
index 858bb9b1..d0d0b413 100644
--- a/src/tagline.zig
+++ b/src/tagline.zig
@@ -23,6 +23,8 @@ pub const context_pane_tail = file_pane_tail ++ " TreeContext";
pub const locations_pane_tail = file_pane_tail ++ " LocationsConfig";
pub const terminal_pane_tail = " " ++ config.terminal_pane_builtins_str;
pub const command_pane_tail = " " ++ config.command_pane_builtins_str;
+/// The mark a tag carried after an unsaved file's name before the grip
+/// showed it; a dump from then still has it in its saved tags.
const dirty_marker = " *";
pub const legacy_pane_tail = " Del";
pub const legacy_file_pane_tail = " Save Del";
@@ -134,12 +136,9 @@ pub fn pathPrefix(arena: std.mem.Allocator, pane: *Pane) ![]const u8 {
var idbuf: [48]u8 = undefined;
return std.fmt.allocPrint(arena, "{s} {s}", .{ pane.cwdSlice(), exec.replId(&idbuf, pane) });
}
- 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 name;
- }
+ // Unsaved text shows on the grip, as acme's modbutton does, not as a
+ // mark in the text: the prefix is the name alone.
+ if (pane.file) |f| return if (pane.prompt == .name) pane.input.own orelse f.path else f.path;
return pane.cwdSlice();
}