summaryrefslogtreecommitdiff
path: root/src/Output.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Output.zig')
-rw-r--r--src/Output.zig43
1 files changed, 34 insertions, 9 deletions
diff --git a/src/Output.zig b/src/Output.zig
index 3b8e6a7a..1461757f 100644
--- a/src/Output.zig
+++ b/src/Output.zig
@@ -418,6 +418,16 @@ pub fn open(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: []const u
/// Find and Grep share one +Search a directory, each run replacing what
/// the last showed, as acme reuses a directory's +Errors; a pane's own
/// search (LookWord list) keeps a pane a pattern.
+/// Whether `dir` has its Find/Grep +Search open.
+pub fn hasFileSearch(p: *Pardes, dir: []const u8) bool {
+ for (p.panes) |slot| {
+ const f = (slot orelse continue).file orelse continue;
+ const o = f.output orelse continue;
+ if (fileSearch(o.from) and std.mem.eql(u8, std.fs.path.dirname(f.path) orelse "", dir)) return true;
+ }
+ return false;
+}
+
fn fileSearch(from: Origin) bool {
return switch (from) {
.cmd => |c| c == .Find or c == .Grep,
@@ -436,7 +446,9 @@ pub fn fillResults(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: []
const by_arg = std.meta.activeTag(from) != .query;
if (p.locations_config.context == 0 and !p.locations_config.tscontext) {
for (p.panes, 0..) |slot, i| {
- if (i == id) continue;
+ // A directory's +Search is found by its directory, whatever
+ // pane ran the search: that +Search itself too.
+ if (i == id and !fileSearch(from)) continue;
const rp = slot orelse continue;
const rf = if (rp.file) |*f| f else continue;
const output = if (rf.output) |*o| o else continue;
@@ -446,6 +458,7 @@ pub fn fillResults(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: []
if (!locations.sameInput(content, rf.content, rf.location_rows, p.locations_config.layout)) continue;
try setArg(output, arg);
p.gpa.free(content);
+ p.fs.refilled = rp.serial;
p.active = id;
if (traits(from).steps) {
pane.search_pane = i;
@@ -463,11 +476,11 @@ pub fn fillResults(p: *Pardes, id: usize, dir: []const u8, from: Origin, arg: []
anchor = formatted.anchor;
}
for (p.panes, 0..) |slot, i| {
- if (i == id) continue;
const rp = slot orelse continue;
const rf = if (rp.file) |*f| f else continue;
const o = if (rf.output) |*x| x else continue;
const shared = fileSearch(from) and fileSearch(o.from);
+ if (i == id and !shared) continue;
if (!shared and !std.meta.eql(o.from, from)) continue;
if (!shared and by_arg and !std.mem.eql(u8, o.arg(), arg)) continue;
if (!std.mem.eql(u8, std.fs.path.dirname(rf.path) orelse "", dir)) continue;
@@ -555,13 +568,22 @@ pub fn recentText(p: *Pardes, w: *std.Io.Writer, look_rows: bool) !void {
for (p.panes) |slot| if (slot) |pane| if (pane.file) |f| if (f.output == null and std.mem.eql(u8, f.path, e.path)) {
is_open = true;
};
- const state: []const u8 = if (is_open) "open" else "closed";
- if (!look_rows)
- try w.print("{s} {s}\n", .{ state, e.path })
- else if (e.line == 0)
- try w.print("{s} {s}\n", .{ e.path, state })
- else
+ const state: []const u8 = if (is_open) "open" else "(closed)";
+ if (!look_rows) {
+ // A name as /index shows it: one line, a newline in it `\n`.
+ var name_buf: [4 * 4096]u8 = undefined;
+ try w.print("{s} {s}\n", .{ if (is_open) "open" else "closed", pardes.ctlfs.events.shown(e.path, &name_buf) });
+ } else if (e.line == 0) {
+ try w.print("{s} {s}\n", .{ e.path, state });
+ } else if (e.aline != 0 and (e.aline != e.line or e.acol != e.col)) {
+ // A selection: both its ends, in order, `path:L:C-L2:C2`.
+ const a_first = e.aline < e.line or (e.aline == e.line and e.acol < e.col);
+ const s = if (a_first) [2]u32{ e.aline, e.acol } else [2]u32{ e.line, e.col };
+ const t = if (a_first) [2]u32{ e.line, e.col } else [2]u32{ e.aline, e.acol };
+ try w.print("{s}:{d}:{d}-{d}:{d} {s}\n", .{ e.path, s[0], s[1], t[0], t[1], state });
+ } else {
try w.print("{s}:{d}:{d} {s}\n", .{ e.path, e.line, e.col, state });
+ }
}
}
@@ -647,7 +669,10 @@ pub fn openFonts(p: *Pardes, id: usize) !void {
fn openStepped(p: *Pardes, id: usize, from: Origin, content: []u8) !void {
errdefer p.gpa.free(content);
const pane = p.panes[id] orelse return error.MissingPane;
- const dir = if (pane.file) |f| (std.fs.path.dirname(f.path) orelse "/") else pane.cwdSlice();
+ const own = if (pane.file) |f| (std.fs.path.dirname(f.path) orelse "/") else pane.cwdSlice();
+ // A terminal whose shell has not said where it is yet (an init file's
+ // word at boot): the session's directory, not `/`.
+ const dir = if (own.len == 0) p.sessionDir() else own;
const free = p.freeSlot() orelse return error.NoPaneSlots;
_ = try open(p, free, dir, from, "", content);
exec.placeNew(p, id, id, free, .doc);