summaryrefslogtreecommitdiff
path: root/src/exec.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/exec.zig')
-rw-r--r--src/exec.zig39
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 {