commit 718d4ae9c7a5a520f58c2155a6c7b64e1a68a30a
parent 35b39978e5ad17722d20594e66d9157c19f5077f
Author: Byron Torres <b@torresjrjr.com>
Date: Sat, 17 Dec 2022 01:36:46 +0000
add cmd_list(), printer functions
Diffstat:
M | command.ha | | | 22 | +++++++++++++++------- |
M | parse.ha | | | 2 | +- |
M | util.ha | | | 67 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 83 insertions(+), 8 deletions(-)
diff --git a/command.ha b/command.ha
@@ -293,7 +293,19 @@ fn cmd_mark(s: *session, cmd: *command) (void | error) = {
s.buf.lines[n].mark = mark;
};
-fn cmd_list(s: *session, cmd: *command) (void | error) = void;
+fn cmd_list(s: *session, cmd: *command) (void | error) = {
+ const (a, b) = get_range(
+ s,
+ &cmd.linenums,
+ s.buf.cursor,
+ s.buf.cursor,
+ )?;
+ assert_nonzero(s, a)?;
+ debug("cmd_list(): (a, b)=({}, {})", a, b);
+
+ printlistlns(&s.buf, a, b)?;
+ s.buf.cursor = b;
+};
fn cmd_move(s: *session, cmd: *command) (void | error) = {
const (a, b) = get_range(
@@ -351,9 +363,7 @@ fn cmd_number(s: *session, cmd: *command) (void | error) = {
assert_nonzero(s, a)?;
debug("cmd_number(): (a, b)=({}, {})", a, b);
- for (let n = a; n <= b; n += 1) {
- fmt::printfln("{}\t{}", n, s.buf.lines[n].text)!;
- };
+ printnumberlns(&s.buf, a, b)?;
s.buf.cursor = b;
};
@@ -366,9 +376,7 @@ fn cmd_print(s: *session, cmd: *command) (void | error) = {
)?;
assert_nonzero(s, a)?;
- for (let n = a; n <= b; n += 1) {
- fmt::println(s.buf.lines[n].text)!;
- };
+ printlns(&s.buf, a, b)?;
s.buf.cursor = b;
};
diff --git a/parse.ha b/parse.ha
@@ -223,7 +223,7 @@ fn scan_cmdfn(iter: *strings::iterator) commandfn = {
// case 'i' => return &cmd_insert;
case 'j' => return &cmd_join;
case 'k' => return &cmd_mark;
-// case 'l' => return &cmd_list;
+ case 'l' => return &cmd_list;
case 'm' => return &cmd_move;
case 'n' => return &cmd_number;
case 'p' => return &cmd_print;
diff --git a/util.ha b/util.ha
@@ -1,4 +1,6 @@
use fmt;
+use io;
+use strings;
fn cmd_dumpbuffer(s: *session, cmd: *command) (void | error) = {
return dumpbuffer(&s.buf);
@@ -15,3 +17,68 @@ fn debug(fmtstr: str, args: fmt::field...) void = {
fmt::errorf(fmtstr, args...)!;
fmt::errorln("\x1b[m")!;
};
+
+type printer = *fn(_: *buffer, _: size, _: size) (size | io::error);
+
+fn printlns(buf: *buffer, a: size, b: size) (size | io::error) = {
+ let sz = 0z;
+ for (let n = a; n <= b; n += 1) {
+ sz += fmt::println(buf.lines[n].text)?;
+ };
+ return sz;
+};
+
+fn printnumberlns(buf: *buffer, a: size, b: size) (size | io::error) = {
+ let sz = 0z;
+ for (let n = a; n <= b; n += 1) {
+ sz += fmt::printfln("{}\t{}", n, buf.lines[n].text)?;
+ };
+ return sz;
+};
+
+fn printlistlns(buf: *buffer, a: size, b: size) (size | io::error) = {
+ let sz = 0z;
+ for (let n = a; n <= b; n += 1) {
+ sz += printlistln(buf.lines[n].text)?;
+ };
+ return sz;
+};
+
+fn printlistln(text: str) (size | io::error) = {
+ // TODO: handle wrapping (see ed(1) > list command)
+ const iter = strings::iter(text);
+ let sz = 0z;
+
+ for (true) {
+ const r = match (strings::next(&iter)) {
+ case void =>
+ break;
+ case let r: rune =>
+ yield r;
+ };
+
+ sz += switch (r) {
+ case '\\' =>
+ yield fmt::print("\\\\")?;
+ case '\a' =>
+ yield fmt::print("\\a")?;
+ case '\b' =>
+ yield fmt::print("\\b")?;
+ case '\f' =>
+ yield fmt::print("\\f")?;
+ case '\r' =>
+ yield fmt::print("\\r")?;
+ case '\t' =>
+ yield fmt::print("\\t")?;
+ case '\v' =>
+ yield fmt::print("\\v")?;
+ case '$' =>
+ yield fmt::print("\\$")?;
+ case =>
+ yield fmt::print(r)?;
+ };
+ };
+
+ sz += fmt::println('$')?;
+ return sz;
+};