commit eddd47458d41cb267c74ea07b26dce189f9c844b
parent b9d8945d34c6e559a87400a99c7c4f6fadabcd2b
Author: Byron Torres <b@torresjrjr.com>
Date: Sun, 11 Dec 2022 03:18:36 +0000
reorganise command code, create stubs
Diffstat:
M | command.ha | | | 253 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
M | parse.ha | | | 25 | +++---------------------- |
2 files changed, 160 insertions(+), 118 deletions(-)
diff --git a/command.ha b/command.ha
@@ -4,6 +4,25 @@ use fs;
use io;
use os;
+type command = struct {
+ addrs: []address,
+ linenums: []size,
+ cmdfn: commandfn,
+ suffix: suffix,
+ arg: str,
+ input: []str,
+ subcmds: []command,
+};
+
+type commandfn = *fn(_: *session, _: *command) (void | error);
+
+type suffix = enum {
+ NONE,
+ LIST,
+ NUMBER,
+ PRINT,
+};
+
type error = !(
badaddress
| nofilename
@@ -18,6 +37,15 @@ type buffermodified = !void;
type unexpectedaddress = !void;
+// Executes the session's .cmd command.
+fn execute(s: *session, cmd: *command) (void | error) = {
+ // TODO: move this into the cmd_* functions?
+ exec_addrs(s, cmd)?;
+ defer delete(cmd.linenums[..]); // TODO: write finish_cmd()
+
+ cmd.cmdfn(s, cmd)?;
+};
+
fn exec_addrs(s: *session, cmd: *command) (void | error) = {
for (let i = 0z; i < len(cmd.addrs); i += 1) {
const addr = cmd.addrs[i];
@@ -42,14 +70,6 @@ fn exec_addrs(s: *session, cmd: *command) (void | error) = {
};
};
-// Executes the session's .cmd command.
-fn execute(s: *session, cmd: *command) (void | error) = {
- // TODO: move this into the cmd_* functions?
- exec_addrs(s, cmd)?;
- defer delete(cmd.linenums[..]); // TODO: write finish_cmd()
-
- cmd.cmdfn(s, cmd)?;
-};
fn get_range(s: *session, lns: *[]size, a: size, b: size) ((size, size) | badaddress) = {
const (a, b) = if (len(lns) == 0) {
@@ -82,16 +102,85 @@ fn assert_noaddrs(s: *session, lns: []size) (void | unexpectedaddress) = {
};
};
-fn cmd_prompt(s: *session, cmd: *command) (void | error) = {
+fn cmd_append(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_change(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_delete(s: *session, cmd: *command) (void | error) = {
+ const (a, b) = get_range(
+ s,
+ &cmd.linenums,
+ s.buf.cursor,
+ s.buf.cursor,
+ )?;
+ if (a < 1) return badaddress;
+
+ buf_delete(&s.buf, a, b);
+ s.buf.cursor = if (len(s.buf.lines) == 1) {
+ yield 0;
+ } else if (len(s.buf.lines) == a) {
+ yield a - 1;
+ } else {
+ yield a;
+ };
+};
+
+fn cmd_edit(s: *session, cmd: *command) (void | error) = {
assert_noaddrs(s, cmd.linenums)?;
- s.promptmode = !s.promptmode;
+
+ if (s.buf.modified && !s.warned) {
+ errormsg(s, "Warning: buffer modified");
+ s.warned = true;
+ return buffermodified;
+ };
+
+ const fname = if (len(cmd.arg) != 0) {
+ s.buf.filename = cmd.arg;
+ yield cmd.arg;
+ } else {
+ yield if (len(s.buf.filename) != 0) {
+ yield s.buf.filename;
+ } else {
+ errormsg(s, "No current filename");
+ return nofilename;
+ };
+ };
+
+ const h = match (os::open(fname)) {
+ case let err: fs::error =>
+ errormsg(s, fs::strerror(err));
+ return err;
+ case let h: io::file =>
+ yield h: io::handle;
+ };
+ defer io::close(h)!;
+
+ buf_deleteall(&s.buf);
+ const (sz, _) = buf_read(&s.buf, h, 0);
+ if (!s.suppressmode) {
+ fmt::println(sz)!;
+ };
+ s.buf.cursor = len(s.buf.lines) - 1;
};
-fn cmd_linenumber(s: *session, cmd: *command) (void | error) = {
- const n = get_linenum(cmd.linenums, addr_lastline(&s.buf));
- fmt::println(n)!;
+fn cmd_edit_forced(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_filename(s: *session, cmd: *command) (void | error) = {
+ assert_noaddrs(s, cmd.linenums)?;
+ if (len(cmd.arg) != 0) {
+ s.buf.filename = cmd.arg;
+ };
+ if (len(s.buf.filename) == 0) {
+ errormsg(s, "No current filename");
+ return nofilename;
+ };
+ fmt::println(s.buf.filename)!;
};
+fn cmd_global(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_global_manual(s: *session, cmd: *command) (void | error) = void;
+
fn cmd_help(s: *session, cmd: *command) (void | error) = {
assert_noaddrs(s, cmd.linenums)?;
if (s.lasterror != "") {
@@ -107,89 +196,52 @@ fn cmd_helpmode(s: *session, cmd: *command) (void | error) = {
};
};
-fn cmd_print(s: *session, cmd: *command) (void | error) = {
+fn cmd_insert(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_join(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_mark(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_list(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_move(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_number(s: *session, cmd: *command) (void | error) = {
const (a, b) = get_range(
s,
&cmd.linenums,
s.buf.cursor,
s.buf.cursor,
)?;
+ if (a < 1) return badaddress;
+
for (let n = a; n <= b; n += 1) {
- fmt::println(s.buf.lines[n].text)!;
+ fmt::printfln("{}\t{}", n, s.buf.lines[n].text)!;
};
s.buf.cursor = b;
};
-fn cmd_number(s: *session, cmd: *command) (void | error) = {
+fn cmd_print(s: *session, cmd: *command) (void | error) = {
const (a, b) = get_range(
s,
&cmd.linenums,
s.buf.cursor,
s.buf.cursor,
)?;
-
for (let n = a; n <= b; n += 1) {
- fmt::printfln("{}\t{}", n, s.buf.lines[n].text)!;
+ fmt::println(s.buf.lines[n].text)!;
};
s.buf.cursor = b;
};
-fn cmd_filename(s: *session, cmd: *command) (void | error) = {
+fn cmd_prompt(s: *session, cmd: *command) (void | error) = {
assert_noaddrs(s, cmd.linenums)?;
- if (len(cmd.arg) != 0) {
- s.buf.filename = cmd.arg;
- };
- if (len(s.buf.filename) == 0) {
- errormsg(s, "No current filename");
- return nofilename;
- };
- fmt::println(s.buf.filename)!;
+ s.promptmode = !s.promptmode;
};
-fn cmd_write(s: *session, cmd: *command) (void | error) = {
- const (a, b) = get_range(
- s,
- &cmd.linenums,
- addr_linenum(&s.buf, 1)!,
- addr_lastline(&s.buf),
- )?;
+fn cmd_quit(s: *session, cmd: *command) (void | error) = void;
- const fname = if (len(cmd.arg) != 0) {
- s.buf.filename = cmd.arg;
- yield cmd.arg;
- } else {
- yield if (len(s.buf.filename) != 0) {
- yield s.buf.filename;
- } else {
- errormsg(s, "No current filename");
- return nofilename;
- };
- };
-
- const h = match (os::open(fname)) {
- case let err: fs::error =>
- yield match (err) {
- case errors::noentry =>
- yield match (os::create(fname, 0o644)) {
- case let h: io::file =>
- yield h: io::handle;
- case let err: fs::error =>
- return errormsg(s, fs::strerror(err));
- };
- case =>
- errormsg(s, fs::strerror(err));
- return err;
- };
- case let h: io::file =>
- yield h: io::handle;
- };
- defer io::close(h)!;
-
- const sz = buf_write(&s.buf, h, a, b);
- if (!s.suppressmode) {
- fmt::println(sz)!;
- };
-};
+fn cmd_quit_forced(s: *session, cmd: *command) (void | error) = void;
fn cmd_read(s: *session, cmd: *command) void = {
const n = get_linenum(cmd.linenums, s.buf.cursor);
@@ -220,12 +272,23 @@ fn cmd_read(s: *session, cmd: *command) void = {
s.buf.cursor = len(s.buf.lines) - 1;
};
-fn cmd_edit(s: *session, cmd: *command) (void | error) = {
- if (s.buf.modified && !s.warned) {
- errormsg(s, "Warning: buffer modified");
- s.warned = true;
- return buffermodified;
- };
+fn cmd_substitute(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_copy(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_undo(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_invglobal(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_invglobal_manual(s: *session, cmd: *command) (void | error) = void;
+
+fn cmd_write(s: *session, cmd: *command) (void | error) = {
+ const (a, b) = get_range(
+ s,
+ &cmd.linenums,
+ addr_linenum(&s.buf, 1)!,
+ addr_lastline(&s.buf),
+ )?;
const fname = if (len(cmd.arg) != 0) {
s.buf.filename = cmd.arg;
@@ -241,38 +304,36 @@ fn cmd_edit(s: *session, cmd: *command) (void | error) = {
const h = match (os::open(fname)) {
case let err: fs::error =>
- errormsg(s, fs::strerror(err));
- return err;
+ yield match (err) {
+ case errors::noentry =>
+ yield match (os::create(fname, 0o644)) {
+ case let h: io::file =>
+ yield h: io::handle;
+ case let err: fs::error =>
+ return errormsg(s, fs::strerror(err));
+ };
+ case =>
+ errormsg(s, fs::strerror(err));
+ return err;
+ };
case let h: io::file =>
yield h: io::handle;
};
defer io::close(h)!;
- buf_deleteall(&s.buf);
- const (sz, _) = buf_read(&s.buf, h, 0);
+ const sz = buf_write(&s.buf, h, a, b);
if (!s.suppressmode) {
fmt::println(sz)!;
};
- s.buf.cursor = len(s.buf.lines) - 1;
};
-fn cmd_delete(s: *session, cmd: *command) (void | error) = {
- const (a, b) = get_range(
- s,
- &cmd.linenums,
- s.buf.cursor,
- s.buf.cursor,
- )?;
- buf_delete(&s.buf, a, b);
- s.buf.cursor = if (len(s.buf.lines) == 1) {
- yield 0;
- } else if (len(s.buf.lines) == a) {
- yield a - 1;
- } else {
- yield a;
- };
+fn cmd_linenumber(s: *session, cmd: *command) (void | error) = {
+ const n = get_linenum(cmd.linenums, addr_lastline(&s.buf));
+ fmt::println(n)!;
};
+fn cmd_shellescape(s: *session, cmd: *command) (void | error) = void;
+
fn cmd_null(s: *session, cmd: *command) (void | error) = {
const n = get_linenum(
cmd.linenums,
diff --git a/parse.ha b/parse.ha
@@ -4,25 +4,6 @@ use ascii;
use strconv;
use strings;
-type command = struct {
- addrs: []address,
- linenums: []size,
- cmdfn: commandfn,
- suffix: suffix,
- arg: str,
- input: []str,
- subcmds: []command,
-};
-
-type commandfn = *fn(_: *session, _: *command) (void | error);
-
-type suffix = enum {
- NONE,
- LIST,
- NUMBER,
- PRINT,
-};
-
// Parses inputted commands. Returns true on terminal input.
fn parse(cmd: *command, input: str) bool = {
if (len(input) != 1) {
@@ -224,11 +205,11 @@ fn scan_cmdfn(iter: *strings::iterator) commandfn = {
switch (r) {
case '=' => return &cmd_linenumber;
// case 'E' => return &cmd_edit_forced;
-// case 'G' => return &cmd_global_interactive;
+// case 'G' => return &cmd_global_manual;
case 'H' => return &cmd_helpmode;
case 'P' => return &cmd_prompt;
// case 'Q' => return &cmd_quit_forced;
-// case 'V' => return &cmd_global_inverse_interactive;
+// case 'V' => return &cmd_invglobal_manual;
// case 'a' => return &cmd_append;
// case 'c' => return &cmd_change;
case 'd' => return &cmd_delete;
@@ -248,7 +229,7 @@ fn scan_cmdfn(iter: *strings::iterator) commandfn = {
// case 's' => return &cmd_substitute;
// case 't' => return &cmd_copy;
// case 'u' => return &cmd_undo;
-// case 'v' => return &cmd_global_inverse;
+// case 'v' => return &cmd_invglobal;
case 'w' => return &cmd_write;
case 'b' => return &cmd_dumpbuffer;