diff options
Diffstat (limited to 'src/exec.zig')
| -rw-r--r-- | src/exec.zig | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/src/exec.zig b/src/exec.zig index eed9297a..7d682d74 100644 --- a/src/exec.zig +++ b/src/exec.zig @@ -643,12 +643,22 @@ pub fn execute(p: *Pardes, id: usize, txt: []const u8) ?usize { /// `execute` for text a gesture took from `id`'s body when `from_body`: /// such text may be a bound REPL's. Run by name (`Exec ...`, whose line /// comes back through `execute`) or written as a command word, never. +/// A line that starts with `#` is a comment, as in a shell: it runs as +/// nothing, silently, wherever a line runs (exec, a ctl, the init file), +/// so DumpConfig's report reads back as configuration whole. +pub fn isComment(line: []const u8) bool { + const t = std.mem.trimStart(u8, line, " \t"); + return t.len > 0 and t[0] == '#'; +} + pub fn executeFrom(p: *Pardes, id: usize, txt: []const u8, from_body: bool) ?usize { - // An empty window runs its session words, and nothing else: no pane to - // run a command for. + if (isComment(commandText(txt))) return null; + // An empty window runs its session words, and a command line in the + // session's directory (execDir), as its workspace tag would. const pane = p.panes[id] orelse { - _ = executeBuiltinLine(p, id, commandText(txt)); - return null; + const cmd = commandText(txt); + if (cmd.len == 0 or executeBuiltinLine(p, id, cmd)) return null; + return runCommand(p, id, cmd); }; const gesture = from_body and config.commandWord(std.mem.trim(u8, txt, " \t\r\n")) == null; const cmd = commandText(txt); @@ -699,7 +709,9 @@ fn runCommand(p: *Pardes, from: usize, line: []const u8) ?usize { p.reportFailure(from, "exec: a command line is at most 1024 bytes"); return null; } - const src = p.panes[from] orelse return null; + // None asking (an empty window): the session's directory, no pane of + // its own to reuse. + const src = p.panes[from]; const dir = p.execDir(from); // A directory that is not there runs nothing, as Tty makes nothing // there: no pane, and the write fails ENOENT. @@ -712,7 +724,7 @@ fn runCommand(p: *Pardes, from: usize, line: []const u8) ?usize { // would hang that job up. // From a column's tag, only a finished pane in that column is reused, // as the new one goes in that column (placeNew). - const reuse: ?usize = if (p.exec_column == null and src.command != null and src.command_done and !src.command_pty) from else for (p.panes, 0..) |slot, i| { + const reuse: ?usize = if (p.exec_column == null and src != null and src.?.command != null and src.?.command_done and !src.?.command_pty) from else for (p.panes, 0..) |slot, i| { const other = slot orelse continue; if (p.exec_column) |c| if (if (layout.findPane(p, i)) |f| f.col != c else true) continue; if (other.command != null and other.command_done and !other.command_pty and std.mem.eql(u8, other.cwdSlice(), dir)) break i; @@ -838,6 +850,7 @@ pub const acme_words = [_]struct { acme: []const u8, pardes: ?[]const u8, hint: pub fn executeBuiltinLine(p: *Pardes, id: usize, txt: []const u8) bool { const raw = commandText(txt); if (raw.len == 0 or p.exec_depth >= max_exec_depth) return false; + if (isComment(raw)) return true; const word_end = std.mem.indexOfAny(u8, raw, " \t") orelse raw.len; var renamed: [1024 + 16]u8 = undefined; const cmd = for (acme_words) |w| { @@ -1032,9 +1045,12 @@ pub fn placeNew(p: *Pardes, from: usize, origin: ?usize, id: usize, kind: NewPan // No pane to halve, but the column holds every pane's minimum // with the new one's: the rows are shared out again, so what is // refused is only what the documented arithmetic cannot hold. - // +Errors goes wherever there is room, last column first; with - // none, its maker says the text some other way (appendErrors). - if (layout.shareColumn(p, f.col)) {} else if (kind == .errors) { + // +Errors and 9P's pane/new go wherever there is room, last + // column first, as acme takes rows from a window that has them + // before saying there are none; with none, +Errors's maker says + // the text some other way (appendErrors), and pane/new is + // refused. + if (layout.shareColumn(p, f.col)) {} else if (kind == .errors or kind == .fs) { layout.removePane(p, id); var c = p.ncol; while (c > 0) { @@ -1051,6 +1067,11 @@ pub fn placeNew(p: *Pardes, from: usize, origin: ?usize, id: usize, kind: NewPan } else { layout.insert(p, f.col, p.col_n[f.col], id); p.unplaced.set(id); + // No pane anywhere can give it rows: pane/new is refused. + if (kind == .fs) { + p.panes[id].?.vweight = 0; + p.reportError(from, "placement", error.NoPaneRoom); + } return; } } else { |
