summaryrefslogtreecommitdiff
path: root/src/exec.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/exec.zig')
-rw-r--r--src/exec.zig34
1 files changed, 27 insertions, 7 deletions
diff --git a/src/exec.zig b/src/exec.zig
index ac6efcdd..8a24969d 100644
--- a/src/exec.zig
+++ b/src/exec.zig
@@ -982,9 +982,30 @@ pub fn executeBuiltinLine(p: *Pardes, id: usize, txt: []const u8) bool {
pub fn applyStartupConfig(p: *Pardes) void {
p.announce = false;
defer p.announce = true;
- var lines = std.mem.splitScalar(u8, p.opts.startup_config orelse return, '\n');
+ const text = p.opts.startup_config orelse return;
+ // A UTF-8 BOM an editor left at its start is no part of its first word.
+ const body = if (std.mem.startsWith(u8, text, "\xEF\xBB\xBF")) text[3..] else text;
+ var lines = std.mem.splitScalar(u8, body, '\n');
+ var number: usize = 0;
while (lines.next()) |line| {
- _ = executeBuiltinLine(p, p.active, line);
+ number += 1;
+ const word = std.mem.trim(u8, line, " \t\r");
+ // `#` starts a comment only at a line's start: a value may hold one
+ // (`#ff0000`).
+ if (word.len == 0 or isComment(word)) continue;
+ const failures = p.fs.failures;
+ const known = executeBuiltinLine(p, p.active, line);
+ if (known and p.fs.failures == failures) continue;
+ // Never silent: a word it has not, or one that failed, is a notice
+ // on the message row and an err in the log, with its line.
+ var why_buf: [320]u8 = undefined;
+ const why: []const u8 = if (!known)
+ std.fmt.bufPrint(&why_buf, "unknown word \"{s}\"", .{word[0..@min(word.len, 64)]}) catch "unknown word"
+ else if (p.fs.said_len > 0) p.fs.said[0..p.fs.said_len] else "failed";
+ var said: [400]u8 = undefined;
+ const line_said = std.fmt.bufPrint(&said, "init file line {d}: {s}", .{ number, why }) catch "init file: a line failed";
+ if (!known) p.reportFailure(p.active, line_said);
+ pardes.ctlfs.events.notePath(p, "err -", line_said);
}
}
@@ -1027,9 +1048,8 @@ pub fn applySettingBuiltin(p: *Pardes, setting: config.Runtime.Setting, arg: ?[]
.theme => {
const want = std.mem.trim(u8, arg orelse return, " \t\r\n");
if (colors.themeIndex(want)) |i| return colors.setThemeIndex(p, i);
- // A config line is not answered on screen (applyStartupConfig
- // runs with announce off); a click or a ctl write is.
- if (!p.announce) return;
+ // A failure is said, the init file's too (applyStartupConfig
+ // logs it with its line): never silent.
// All of it within the 128 bytes a 9P error carries, so a write
// failing with it is cut nowhere: the names get what is left.
const shown = want[0..@min(want.len, 40)];
@@ -1064,10 +1084,10 @@ pub fn applySettingBuiltin(p: *Pardes, setting: config.Runtime.Setting, arg: ?[]
return p.reportFailure(p.active, std.fmt.bufPrint(&text, "Shell: {s}", .{refused}) catch "Shell: no such shell");
}
}
- if (!p.settings.apply(setting, want) and p.announce) p.reportFailure(p.active, "Shell: takes " ++ comptime config.Runtime.takes(.shell).?);
+ if (!p.settings.apply(setting, want)) p.reportFailure(p.active, "Shell: takes " ++ comptime config.Runtime.takes(.shell).?);
},
// Said with what it takes: its words, its range.
- else => if (!p.settings.apply(setting, arg) and p.announce) {
+ else => if (!p.settings.apply(setting, arg)) {
var text: [160]u8 = undefined;
const why = if (config.Runtime.takes(setting.action)) |values| std.fmt.bufPrint(&text, "{s}: takes {s}", .{ setting.word, values }) else std.fmt.bufPrint(&text, "{s}: does not take that value", .{setting.word});
p.reportFailure(p.active, why catch "does not take that value");