ed

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

commit 319166fdb8635a153c2c842426f97f69ea9af51c
parent 75577de0f5b81b5225c671403b12ea690a830346
Author: Byron Torres <b@torresjrjr.com>
Date:   Mon, 20 Feb 2023 00:57:42 +0000

add cmd_append(), cmd_change(), cmd_insert()

Diffstat:
Mcommand.ha | 64+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mmain.ha | 10++++++++--
Mparse.ha | 8+++++++-
3 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/command.ha b/command.ha @@ -177,9 +177,50 @@ fn assert_nonzero(s: *session, n: size) (void | invalidaddress) = { }; }; -fn cmd_append(s: *session, cmd: *command) (void | error) = void; +fn cmd_append(s: *session, cmd: *command) (void | error) = { + const n = get_linenum(cmd.linenums, s.buf.cursor); + + for (let i = 0z; i < len(cmd.input); i += 1) { + const l = alloc(line { text = cmd.input[i], ... }); + debug("cmd_append(): l.text={}", l.text); + buf_insert(&s.buf, n + 1 + i, l); + }; + + s.buf.cursor = n + len(cmd.input); +}; + +fn cmd_change(s: *session, cmd: *command) (void | error) = { + const (a, b) = get_range( + s, + &cmd.linenums, + s.buf.cursor, + s.buf.cursor, + )?; + if (a == 0) { + a = 1; + if (b == 0) { + b = 1; + }; + }; + + buf_delete(&s.buf, a, b); -fn cmd_change(s: *session, cmd: *command) (void | error) = void; + for (let i = 0z; i < len(cmd.input); i += 1) { + const l = alloc(line { text = cmd.input[i], ... }); + debug("cmd_append(): l.text={}", l.text); + buf_insert(&s.buf, a + i, l); + }; + + s.buf.cursor = if (len(cmd.input) == 0) { + yield if (len(s.buf.lines) == a) { + yield a - 1; + } else { + yield a; + }; + } else { + yield a + len(cmd.input) - 1; + }; +}; fn cmd_delete(s: *session, cmd: *command) (void | error) = { const (a, b) = get_range( @@ -265,7 +306,24 @@ fn cmd_helpmode(s: *session, cmd: *command) (void | error) = { }; }; -fn cmd_insert(s: *session, cmd: *command) (void | error) = void; +fn cmd_insert(s: *session, cmd: *command) (void | error) = { + const n = get_linenum(cmd.linenums, s.buf.cursor); + if (n == 0) { + n = 1; + }; + + for (let i = 0z; i < len(cmd.input); i += 1) { + const l = alloc(line { text = cmd.input[i], ... }); + debug("cmd_append(): l.text={}", l.text); + buf_insert(&s.buf, n + i, l); + }; + + s.buf.cursor = if (len(cmd.input) == 0) { + yield n; + } else { + yield n + len(cmd.input) - 1; + }; +}; fn cmd_join(s: *session, cmd: *command) (void | error) = { const (a, b) = get_range( diff --git a/main.ha b/main.ha @@ -82,7 +82,7 @@ export fn main() void = { let cmd = command { ... }; for (true) :repl { - if (s.promptmode) { + if (s.promptmode && s.mode == mode::COMMAND) { fmt::error(s.prompt)!; }; @@ -117,13 +117,19 @@ export fn main() void = { // TODO: handle all ": void"s execute(&s, &cmd): void; //cmd = command { ... }; + } else { + s.mode = mode::INPUT; + continue; }; case mode::INPUT => if (input == ".") { + execute(&s, &cmd): void; + delete(cmd.input[..]); s.mode = mode::COMMAND; continue; }; - append(cmd.input, input); + debug("repl: input={}", input); + append(cmd.input, strings::dup(input)); }; }; diff --git a/parse.ha b/parse.ha @@ -75,11 +75,17 @@ fn parse(cmd: *command, input: str) (bool | parseerror) = { return true; // .[s] where 's' is '(l|n|p)' - case 'a', 'c', 'd', 'h', 'H', 'i', 'j', 'l', 'n', 'p', 'P', 'u', '=' => + case 'd', 'h', 'H', 'j', 'l', 'n', 'p', 'P', 'u', '=' => cmd.printmode = scan_suffix(&iter); scan_end_assert(&iter)?; return true; + // .[s] + case 'a', 'c', 'i' => + cmd.printmode = scan_suffix(&iter); + scan_end_assert(&iter)?; + return false; + // .[s][ ]<addr> case 'm', 't' => cmd.printmode = scan_suffix(&iter);