ed

[hare] The standard editor
Log | Files | Refs | README | LICENSE

commit 1331f5dd82546646006e0e44e2ea67f15a4e82db
parent 36318f5a39dde5d9ba3c434d788030bf8c8c8cd1
Author: Byron Torres <b@torresjrjr.com>
Date:   Thu, 28 Dec 2023 11:38:31 +0000

unify ParseError and CmdError for strerror

Diffstat:
Mcommand.ha | 72++++++++++++++++++++++++++++++++++++------------------------------------
Mexecute.ha | 16+++++++++-------
Mmain.ha | 21+++++++++++++++++++--
3 files changed, 64 insertions(+), 45 deletions(-)

diff --git a/command.ha b/command.ha @@ -20,7 +20,7 @@ type Command = struct { subcmds: []Command, }; -type CommandFn = *fn(*Session, *Command) (void | Error); +type CommandFn = *fn(*Session, *Command) (void | CmdError); type PrintMode = enum { NONE, @@ -29,7 +29,7 @@ type PrintMode = enum { PRINT, }; -type Error = !( +type CmdError = !( InvalidAddress | UnexpectedAddress | InvalidDestination @@ -87,7 +87,7 @@ fn lookupcmd(name: rune) CommandFn = { }; }; -fn cmd_append(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_append(s: *Session, cmd: *Command) (void | CmdError) = { const n = get_linenum(cmd.linenums, s.buf.cursor); for (let i = 0z; i < len(cmd.input); i += 1) { @@ -99,7 +99,7 @@ fn cmd_append(s: *Session, cmd: *Command) (void | Error) = { s.buf.cursor = n + len(cmd.input); }; -fn cmd_change(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_change(s: *Session, cmd: *Command) (void | CmdError) = { const (a, b) = get_range( s, &cmd.linenums, @@ -132,7 +132,7 @@ fn cmd_change(s: *Session, cmd: *Command) (void | Error) = { }; }; -fn cmd_delete(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_delete(s: *Session, cmd: *Command) (void | CmdError) = { const (a, b) = get_range( s, &cmd.linenums, @@ -151,7 +151,7 @@ fn cmd_delete(s: *Session, cmd: *Command) (void | Error) = { }; }; -fn cmd_edit(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_edit(s: *Session, cmd: *Command) (void | CmdError) = { assert_noaddrs(s, cmd.linenums)?; if (s.buf.modified && !s.warned) { @@ -184,9 +184,9 @@ fn cmd_edit(s: *Session, cmd: *Command) (void | Error) = { s.buf.cursor = len(s.buf.lines) - 1; }; -fn cmd_edit_forced(s: *Session, cmd: *Command) (void | Error) = void; +fn cmd_edit_forced(s: *Session, cmd: *Command) (void | CmdError) = void; -fn cmd_filename(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_filename(s: *Session, cmd: *Command) (void | CmdError) = { assert_noaddrs(s, cmd.linenums)?; if (len(cmd.arg) != 0) { s.buf.filename = cmd.arg; @@ -197,26 +197,26 @@ fn cmd_filename(s: *Session, cmd: *Command) (void | Error) = { fmt::println(s.buf.filename)!; }; -fn cmd_global(s: *Session, cmd: *Command) (void | Error) = void; +fn cmd_global(s: *Session, cmd: *Command) (void | CmdError) = void; -fn cmd_global_manual(s: *Session, cmd: *Command) (void | Error) = void; +fn cmd_global_manual(s: *Session, cmd: *Command) (void | CmdError) = void; -fn cmd_help(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_help(s: *Session, cmd: *Command) (void | CmdError) = { assert_noaddrs(s, cmd.linenums)?; - if (s.lasterror is Error) { - fmt::println(strerror(s.lasterror as Error))!; + if (s.lasterror is CmdError) { + fmt::println(strerror(s.lasterror as CmdError))!; }; }; -fn cmd_helpmode(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_helpmode(s: *Session, cmd: *Command) (void | CmdError) = { assert_noaddrs(s, cmd.linenums)?; s.helpmode = !s.helpmode; - if (s.helpmode && s.lasterror is Error) { - fmt::println(strerror(s.lasterror as Error))!; + if (s.helpmode && s.lasterror is CmdError) { + fmt::println(strerror(s.lasterror as CmdError))!; }; }; -fn cmd_insert(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_insert(s: *Session, cmd: *Command) (void | CmdError) = { const n = get_linenum(cmd.linenums, s.buf.cursor); const n = if (n == 0) 1z else n; @@ -233,7 +233,7 @@ fn cmd_insert(s: *Session, cmd: *Command) (void | Error) = { }; }; -fn cmd_join(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_join(s: *Session, cmd: *Command) (void | CmdError) = { const (a, b) = get_range( s, &cmd.linenums, @@ -267,7 +267,7 @@ fn cmd_join(s: *Session, cmd: *Command) (void | Error) = { buf_insert(&s.buf, a, newline); }; -fn cmd_mark(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_mark(s: *Session, cmd: *Command) (void | CmdError) = { const n = get_linenum(cmd.linenums, s.buf.cursor); assert_nonzero(s, n)?; @@ -304,7 +304,7 @@ fn cmd_mark(s: *Session, cmd: *Command) (void | Error) = { s.buf.lines[n].mark = mark; }; -fn cmd_list(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_list(s: *Session, cmd: *Command) (void | CmdError) = { const (a, b) = get_range( s, &cmd.linenums, @@ -318,7 +318,7 @@ fn cmd_list(s: *Session, cmd: *Command) (void | Error) = { s.buf.cursor = b; }; -fn cmd_move(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_move(s: *Session, cmd: *Command) (void | CmdError) = { const (a, b) = get_range( s, &cmd.linenums, @@ -364,7 +364,7 @@ fn cmd_move(s: *Session, cmd: *Command) (void | Error) = { s.buf.cursor = dest - 1 + len(ls); }; -fn cmd_number(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_number(s: *Session, cmd: *Command) (void | CmdError) = { const (a, b) = get_range( s, &cmd.linenums, @@ -378,7 +378,7 @@ fn cmd_number(s: *Session, cmd: *Command) (void | Error) = { s.buf.cursor = b; }; -fn cmd_print(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_print(s: *Session, cmd: *Command) (void | CmdError) = { const (a, b) = get_range( s, &cmd.linenums, @@ -391,16 +391,16 @@ fn cmd_print(s: *Session, cmd: *Command) (void | Error) = { s.buf.cursor = b; }; -fn cmd_prompt(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_prompt(s: *Session, cmd: *Command) (void | CmdError) = { assert_noaddrs(s, cmd.linenums)?; s.promptmode = !s.promptmode; }; -fn cmd_quit(s: *Session, cmd: *Command) (void | Error) = void; +fn cmd_quit(s: *Session, cmd: *Command) (void | CmdError) = void; -fn cmd_quit_forced(s: *Session, cmd: *Command) (void | Error) = void; +fn cmd_quit_forced(s: *Session, cmd: *Command) (void | CmdError) = void; -fn cmd_read(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_read(s: *Session, cmd: *Command) (void | CmdError) = { const n = get_linenum(cmd.linenums, s.buf.cursor); const fname = if (len(cmd.arg) != 0) { s.buf.filename = cmd.arg; @@ -423,7 +423,7 @@ fn cmd_read(s: *Session, cmd: *Command) (void | Error) = { s.buf.cursor = len(s.buf.lines) - 1; }; -fn cmd_substitute(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_substitute(s: *Session, cmd: *Command) (void | CmdError) = { const (a, b) = get_range( s, &cmd.linenums, @@ -469,7 +469,7 @@ fn cmd_substitute(s: *Session, cmd: *Command) (void | Error) = { }; }; -fn cmd_copy(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_copy(s: *Session, cmd: *Command) (void | CmdError) = { const (a, b) = get_range( s, &cmd.linenums, @@ -499,13 +499,13 @@ fn cmd_copy(s: *Session, cmd: *Command) (void | Error) = { s.buf.cursor = dest - 1 + len(ls); }; -fn cmd_undo(s: *Session, cmd: *Command) (void | Error) = void; +fn cmd_undo(s: *Session, cmd: *Command) (void | CmdError) = void; -fn cmd_invglobal(s: *Session, cmd: *Command) (void | Error) = void; +fn cmd_invglobal(s: *Session, cmd: *Command) (void | CmdError) = void; -fn cmd_invglobal_manual(s: *Session, cmd: *Command) (void | Error) = void; +fn cmd_invglobal_manual(s: *Session, cmd: *Command) (void | CmdError) = void; -fn cmd_write(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_write(s: *Session, cmd: *Command) (void | CmdError) = { const (a, b) = get_range( s, &cmd.linenums, @@ -544,12 +544,12 @@ fn cmd_write(s: *Session, cmd: *Command) (void | Error) = { }; }; -fn cmd_linenumber(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_linenumber(s: *Session, cmd: *Command) (void | CmdError) = { const n = get_linenum(cmd.linenums, addr_lastline(&s.buf)); fmt::println(n)!; }; -fn cmd_shellescape(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_shellescape(s: *Session, cmd: *Command) (void | CmdError) = { let iter = strings::iter(cmd.arg); let new = memio::dynamic(); defer io::close(&new)!; let preview = false; @@ -613,7 +613,7 @@ fn cmd_shellescape(s: *Session, cmd: *Command) (void | Error) = { s.prev_shcmd = shcmdline; }; -fn cmd_null(s: *Session, cmd: *Command) (void | Error) = { +fn cmd_null(s: *Session, cmd: *Command) (void | CmdError) = { const n = get_linenum( cmd.linenums, addr_nextline(&s.buf, s.buf.cursor), diff --git a/execute.ha b/execute.ha @@ -1,11 +1,12 @@ // Executes the Session's .cmd Command. -fn execute(s: *Session, cmd: *Command) (void | Error) = { +fn execute(s: *Session, cmd: *Command) (void | CmdError) = { // TODO: move this into the cmd_* functions? match (exec_addrs(s, cmd)) { case void => void; - case let err: Error => + case let err: CmdError => delete(cmd.linenums[..]); - return errormsg(s, err); + errormsg(s, err); + return err; }; // TODO: write finish_cmd() // TODO: finish the Command at a higher level (main()) ?. @@ -13,12 +14,13 @@ fn execute(s: *Session, cmd: *Command) (void | Error) = { match (lookupcmd(cmd.cmdname)(s, cmd)) { case void => void; - case let err: Error => - return errormsg(s, err); + case let err: CmdError => + errormsg(s, err); + return err; }; }; -fn exec_addrs(s: *Session, cmd: *Command) (void | Error) = { +fn exec_addrs(s: *Session, cmd: *Command) (void | CmdError) = { for (let i = 0z; i < len(cmd.addrs); i += 1) { const addr = cmd.addrs[i]; let n = exec_addr(s, addr)?; @@ -37,7 +39,7 @@ fn exec_addrs(s: *Session, cmd: *Command) (void | Error) = { }; }; -fn exec_addr(s: *Session, addr: Address) (size | Error) = { +fn exec_addr(s: *Session, addr: Address) (size | CmdError) = { match (addr.addrtype) { case let n: size => return addr_linenum(&s.buf, n)?; diff --git a/main.ha b/main.ha @@ -25,6 +25,8 @@ type InputMode = enum { TEXT, }; +type Error = (ParseError | CmdError); + export fn main() void = { const help: [_]getopt::help = [ "standard line editor", @@ -143,18 +145,18 @@ fn exit_usage(help: []getopt::help) never = { os::exit(1); }; -fn errormsg(s: *Session, err: Error) Error = { +fn errormsg(s: *Session, err: Error) void = { fmt::errorln('?')!; let errmsg = strerror(err); if (s.helpmode) { fmt::errorfln(errmsg)!; }; s.lasterror = err; - return err; }; fn strerror(err: Error) str = { match (err) { + // CmdError case InvalidAddress => return "Invalid address"; case NoFilename => @@ -173,5 +175,20 @@ fn strerror(err: Error) str = { return regex::strerror(e); case let e: fs::error => return fs::strerror(e); + // ParseError + case UnknownCommand => + return "Unknown command"; + case UnexpectedSuffix => + return "Unexpected suffix"; + case TrailingCharacters => + return "Trailing characters"; + case ExpectedArgument => + return "Expected argument"; + case ExpectedMark => + return "Expected mark"; + case InvalidDelimiter => + return "Invalid delimiter"; + case ExpectedDelimiter => + return "Expected delimiter"; }; };