commit 9c424f72cc0e2c42ae646ed84f3dff3c22d50f7d
parent bf56170ec27ec0f4877c419a921fcdea61951750
Author: Byron Torres <b@torresjrjr.com>
Date: Sat, 6 Jan 2024 21:08:54 +0000
add error for invalid global subcmd
Diffstat:
3 files changed, 34 insertions(+), 17 deletions(-)
diff --git a/buffer.ha b/buffer.ha
@@ -49,6 +49,10 @@ fn buf_delete(buf: *Buffer, a: size, b: size) void = {
debug("buf_delete(a={}, b={})", a, b);
// buf_wipetrash(buf);
+ // The G command requires changed lines to be unmarked.
+ // Command functions "change" lines using buf_delete() first.
+ // If a line is trashed, it is effectively unmarked.
+ // The G command function unmarks all lines first anyway.
//for (let i = 0z; i < len(buf.lines); i += 1) {
// buf.lines[i].globalmark = false;
//};
diff --git a/command.ha b/command.ha
@@ -38,6 +38,8 @@ type CmdError = !(
| BufferModified
| NoMatch
| NoPrevShCmd
+ | NoPrevGlobalSubCmd
+ | InvalidGlobalSubCmd
| regex::error
| fs::error
);
@@ -52,6 +54,10 @@ type BufferModified = !void;
type NoPrevShCmd = !void;
+type NoPrevGlobalSubCmd = !void;
+
+type InvalidGlobalSubCmd = !rune;
+
fn command_finish(cmd: *Command) void = {
//debug("command_finish(): delete(cmd.linenums[..])");
delete(cmd.linenums[..]);
@@ -280,7 +286,7 @@ fn cmd_global_interative(s: *Session, cmd: *Command) (void | Error) = {
};
};
- let prevsubcmd: (void | Command) = void;
+ let prevsubcmd: (void | Command) = void; // TODO: handle mem
for :marks (true) {
// find next global-marked line
@@ -298,19 +304,26 @@ fn cmd_global_interative(s: *Session, cmd: *Command) (void | Error) = {
fmt::println(line.text)!;
- let subcmd = parse(s.input)!;
+ // TODO: handle termination by SIGINT signal
+
+ // TODO: handle mem
+ // TODO: just use 'parse()?' when compiler allows
+ //let subcmd = parse(s.input)?;
+ let subcmd = match (parse(s.input)) {
+ case let c: Command =>
+ yield c;
+ case let e: ParseError =>
+ return e;
+ case let e: InteractionError =>
+ return e;
+ };
// write new parse_global_interactive() function instead
// as to avoid reading multiple lines in the case of
// 'a', 'c', 'i' ?
switch (subcmd.cmdname) {
case 'a', 'c', 'i', 'g', 'G', 'v', 'V' =>
- // TODO: how to handle?
- // return !InvalidGlobalInteractiveSubcmd; ?
- fmt::printfln(
- "Error: Invalid interactive global subcommand '{}'",
- subcmd.cmdname,
- )!;
+ errormsg(s, subcmd.cmdname: InvalidGlobalSubCmd);
continue;
case NUL =>
line.globalmark = false;
@@ -318,8 +331,7 @@ fn cmd_global_interative(s: *Session, cmd: *Command) (void | Error) = {
case '&' =>
match (prevsubcmd) {
case void =>
- // TODO: return NoPrevGlobalSubCmd;
- abort("global interactive: &: no previous command");
+ return NoPrevGlobalSubCmd;
case let prevsubcmd: Command =>
subcmd = prevsubcmd;
};
@@ -332,9 +344,6 @@ fn cmd_global_interative(s: *Session, cmd: *Command) (void | Error) = {
execute(s, &subcmd)?;
- // TODO: test if line was modified.
- // TODO: make cmd_ functions save to session whether line was
- // modified, instead of here?
line.globalmark = false;
};
};
diff --git a/main.ha b/main.ha
@@ -22,7 +22,7 @@ type Session = struct{
prev_shcmd: (str | void),
};
-type Error = !(...InteractionError | ParseError | CmdError);
+type Error = !(...InteractionError | ...ParseError | ...CmdError);
def help: [_]getopt::help = [
"standard line editor",
@@ -99,7 +99,7 @@ export fn main() void = {
defer command_finish(&cmd);
if (cmd.cmdname == '&') {
- errormsg(&s, strerror('&': UnknownCommand));
+ errormsg(&s, '&': UnknownCommand);
continue;
};
@@ -158,14 +158,18 @@ fn strerror(err: Error) str = {
return "No match";
case NoPrevShCmd =>
return "No previous shell command";
+ case NoPrevGlobalSubCmd =>
+ return "No previous global subcommand";
+ case let e: InvalidGlobalSubCmd =>
+ return "Invalid interactive global subcommand"; // TODO: append 'e'?
case let e: regex::error =>
return regex::strerror(e);
case let e: fs::error =>
debug("foo");
return fs::strerror(e);
// ParseError
- case UnknownCommand =>
- return "Unknown command";
+ case let e: UnknownCommand =>
+ return "Unknown command"; // TODO: append 'e'?
case UnexpectedSuffix =>
return "Unexpected suffix";
case TrailingCharacters =>