ed

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

commit 1cc35875af4ad60084dc16c61fa9fc833c65d297
parent f3608da092b501d946629acec907fbc3edebfcfe
Author: Byron Torres <b@torresjrjr.com>
Date:   Sun, 18 Dec 2022 22:34:19 +0000

cmdfn -> cmdname

Diffstat:
Mcommand.ha | 39+++++++++++++++++++++++++++++++++++++--
Mparse.ha | 117++++++++++++++++++++++---------------------------------------------------------
2 files changed, 69 insertions(+), 87 deletions(-)

diff --git a/command.ha b/command.ha @@ -9,7 +9,7 @@ use strings; type command = struct { addrs: []address, linenums: []size, - cmdfn: commandfn, + cmdname: rune, printmode: printmode, arg: str, arg2: str, @@ -46,6 +46,41 @@ type nofilename = !void; type buffermodified = !void; +fn lookupcmd(name: rune) commandfn = { + switch (name) { + case 'a' => return &cmd_append; + case 'c' => return &cmd_change; + case 'd' => return &cmd_delete; + case 'e' => return &cmd_edit; + case 'E' => return &cmd_edit_forced; + case 'f' => return &cmd_filename; + case 'g' => return &cmd_global; + case 'G' => return &cmd_global_manual; + case 'h' => return &cmd_help; + case 'H' => return &cmd_helpmode; + case 'i' => return &cmd_insert; + case 'j' => return &cmd_join; + case 'k' => return &cmd_mark; + case 'l' => return &cmd_list; + case 'm' => return &cmd_move; + case 'n' => return &cmd_number; + case 'p' => return &cmd_print; + case 'P' => return &cmd_prompt; + case 'q' => return &cmd_quit; + case 'Q' => return &cmd_quit_forced; + case 'r' => return &cmd_read; + case 's' => return &cmd_substitute; + case 't' => return &cmd_copy; + case 'u' => return &cmd_undo; + case 'v' => return &cmd_invglobal; + case 'V' => return &cmd_invglobal_manual; + case 'w' => return &cmd_write; + case '=' => return &cmd_linenumber; + case '!' => return &cmd_shellescape; + case '\x00' => return &cmd_null; + }; +}; + // Executes the session's .cmd command. fn execute(s: *session, cmd: *command) (void | error) = { // TODO: move this into the cmd_* functions? @@ -59,7 +94,7 @@ fn execute(s: *session, cmd: *command) (void | error) = { // TODO: finish the command at a higher level (main()) ?. defer delete(cmd.linenums[..]); - match (cmd.cmdfn(s, cmd)) { + match (lookupcmd(cmd.cmdname)(s, cmd)) { case void => void; case let err: error => return errormsg(s, err); diff --git a/parse.ha b/parse.ha @@ -32,28 +32,20 @@ fn parse(cmd: *command, input: str) (bool | parseerror) = { const iter = strings::iter(input); cmd.addrs = scan_addrs(&iter); - cmd.cmdfn = scan_cmdfn(&iter)?; + cmd.cmdname = scan_cmdname(&iter)?; - switch (cmd.cmdfn) { - case // [ ] - &cmd_null, - => + switch (cmd.cmdname) { + // [ ] + case '\x00' => return true; - case // (q|Q) - &cmd_quit, - &cmd_quit_forced, - => + // (q|Q) + case 'q', 'Q' => scan_end_assert(&iter)?; return true; - case // .[ <file>] - &cmd_edit, - &cmd_edit_forced, - &cmd_filename, - &cmd_read, - &cmd_write, - => + // .[ <file>] + case 'e', 'E', 'f', 'r', 'w' => if (scan_blanks(&iter) == 0) { match (strings::next(&iter)) { case let r: rune => @@ -66,9 +58,8 @@ fn parse(cmd: *command, input: str) (bool | parseerror) = { return true; }; - case // k<x> - &cmd_mark, - => + // k<x> + case 'k' => match (strings::next(&iter)) { case let r: rune => cmd.arg = strings::fromrunes([r]); @@ -78,43 +69,25 @@ fn parse(cmd: *command, input: str) (bool | parseerror) = { scan_end_assert(&iter)?; return true; - case // !<shellcmd> - &cmd_shellescape, - => + // !<shellcmd> + case '!' => cmd.arg = scan_rest(&iter); return true; - case // .[s] where 's' is '(l|n|p)' - &cmd_append, - &cmd_change, - &cmd_delete, - &cmd_help, - &cmd_helpmode, - &cmd_insert, - &cmd_join, - &cmd_list, - &cmd_number, - &cmd_print, - &cmd_prompt, - &cmd_undo, - &cmd_linenumber, - => + // .[s] where 's' is '(l|n|p)' + case 'a', 'c', 'd', 'h', 'H', 'i', 'j', 'l', 'n', 'p', 'P', 'u', '=' => cmd.printmode = scan_suffix(&iter); scan_end_assert(&iter)?; return true; - case // .[s][ ]<addr> - &cmd_move, - &cmd_copy, - => + // .[s][ ]<addr> + case 'm', 't' => cmd.printmode = scan_suffix(&iter); cmd.arg = scan_rest(&iter); return true; - case // ./<regex>[/] - &cmd_global_manual, - &cmd_invglobal_manual, - => + // ./<regex>[/] where delimiter '/' is arbitrary + case 'G', 'V' => const delim = match (strings::next(&iter)) { case void => return expectedargument; @@ -130,9 +103,8 @@ fn parse(cmd: *command, input: str) (bool | parseerror) = { scan_end_assert(&iter)?; return true; - case // s/<regex>/[<replace>[/[<flags>]]] - &cmd_substitute, - => + // s/<regex>/[<replace>[/[<flags>]]] + case 's' => const delim = match (strings::next(&iter)) { case void => return expectedargument; @@ -158,10 +130,8 @@ fn parse(cmd: *command, input: str) (bool | parseerror) = { cmd.arg3 = scan_rest(&iter); // TODO: scan properly here? return true; - case // ./regex/CMDLIST - &cmd_global, - &cmd_invglobal, - => + // ./<regex>/<cmdlist...> + case 'g', 'v' => abort("TODO: parse: global, invglobal"); case => @@ -350,47 +320,24 @@ fn scan_offset(iter: *strings::iterator) int = { }; }; -fn scan_cmdfn(iter: *strings::iterator) (commandfn | unknowncommand)= { +fn scan_cmdname(iter: *strings::iterator) (rune | unknowncommand)= { scan_blanks(iter); let r = match (strings::next(iter)) { case void => - return &cmd_null; + return '\x00'; case let r: rune => yield r; }; switch (r) { - case 'a' => return &cmd_append; - case 'c' => return &cmd_change; - case 'd' => return &cmd_delete; - case 'e' => return &cmd_edit; - case 'E' => return &cmd_edit_forced; - case 'f' => return &cmd_filename; - case 'g' => return &cmd_global; - case 'G' => return &cmd_global_manual; - case 'h' => return &cmd_help; - case 'H' => return &cmd_helpmode; - case 'i' => return &cmd_insert; - case 'j' => return &cmd_join; - case 'k' => return &cmd_mark; - case 'l' => return &cmd_list; - case 'm' => return &cmd_move; - case 'n' => return &cmd_number; - case 'p' => return &cmd_print; - case 'P' => return &cmd_prompt; - case 'q' => return &cmd_quit; - case 'Q' => return &cmd_quit_forced; - case 'r' => return &cmd_read; - case 's' => return &cmd_substitute; - case 't' => return &cmd_copy; - case 'u' => return &cmd_undo; - case 'v' => return &cmd_invglobal; - case 'V' => return &cmd_invglobal_manual; - case 'w' => return &cmd_write; - case '=' => return &cmd_linenumber; - case '!' => return &cmd_shellescape; -// case 'b' => return &cmd_dumpbuffer; - case => return r: unknowncommand; + case + 'a', 'c', 'd', 'e', 'E', 'f', 'g', 'G', 'h', 'H', + 'i', 'j', 'k', 'l', 'm', 'n', 'p', 'P', 'q', 'Q', + 'r', 's', 't', 'u', 'v', 'V', 'w', '=', '!', + => + return r; + case => + return r: unknowncommand; }; };