commit d5d23ab6a6497a337e79f55b3a1e4d80a454ff2b
parent 9508bae0bfd364cc1e60305b9c310dc836db18c9
Author: Byron Torres <b@torresjrjr.com>
Date: Sat, 6 Jan 2024 12:43:52 +0000
add cmd_quit, Quit; for style
Diffstat:
4 files changed, 89 insertions(+), 18 deletions(-)
diff --git a/buffer.ha b/buffer.ha
@@ -10,6 +10,7 @@ type Buffer = struct{
trash: []*Line,
cursor: size,
modified: bool,
+ written: bool,
};
type Line = struct{
@@ -29,6 +30,8 @@ fn buf_insert(buf: *Buffer, n: size, ls: *Line...) void = {
// debug("buf_insert(): ls[{}].text='{}'", i, ls[i].text);
// };
insert(buf.lines[n], ls...);
+ if (buf.written)
+ buf.modified = true;
};
fn buf_deleteall(buf: *Buffer) void = {
@@ -38,6 +41,8 @@ fn buf_deleteall(buf: *Buffer) void = {
insert(buf.trash[0], buf.lines[1..]...);
delete(buf.lines[1..]);
};
+ if (buf.written)
+ buf.modified = true;
};
fn buf_delete(buf: *Buffer, a: size, b: size) void = {
@@ -46,6 +51,8 @@ fn buf_delete(buf: *Buffer, a: size, b: size) void = {
insert(buf.trash[0], buf.lines[a..b+1]...);
delete(buf.lines[a..b+1]);
+ if (buf.written)
+ buf.modified = true;
};
fn buf_read(buf: *Buffer, src: io::handle, a: size) ((size, size) | io::error | encoding::utf8::invalid) = {
@@ -69,15 +76,17 @@ fn buf_read(buf: *Buffer, src: io::handle, a: size) ((size, size) | io::error |
};
insert(buf.lines[a + 1], ls...);
+ if (buf.written)
+ buf.modified = true;
const lenls = len(ls);
return (sz, lenls);
};
fn buf_write(buf: *Buffer, dest: io::handle, a: size, b: size) (size | io::error) = {
let sz = 0z;
- for (let n = a; n <= b; n += 1) {
+ for (let n = a; n <= b; n += 1)
sz += fmt::fprintln(dest, buf.lines[n].text)?;
- };
+ buf.written = true; // TODO: move into cmd_write() ?
return sz;
};
diff --git a/command.ha b/command.ha
@@ -105,6 +105,8 @@ fn lookupcmd(name: rune) CommandFn = {
};
fn cmd_append(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const n = get_linenum(cmd.linenums, s.buf.cursor);
for (let i = 0z; i < len(cmd.textinput); i += 1) {
@@ -117,6 +119,8 @@ fn cmd_append(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_change(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -150,6 +154,8 @@ fn cmd_change(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_delete(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -172,7 +178,7 @@ fn cmd_edit(s: *Session, cmd: *Command) (void | Error) = {
assert_noaddrs(s, cmd.linenums)?;
if (s.buf.modified && !s.warned) {
- s.warned = true; // TODO: reset this every Command somehow
+ s.warned = true;
return BufferModified;
};
@@ -205,6 +211,8 @@ fn cmd_edit(s: *Session, cmd: *Command) (void | Error) = {
fn cmd_edit_forced(s: *Session, cmd: *Command) (void | Error) = void;
fn cmd_filename(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
assert_noaddrs(s, cmd.linenums)?;
if (cmd.arg1 != "") {
@@ -223,6 +231,8 @@ fn cmd_filename(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_global(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -235,6 +245,8 @@ fn cmd_global(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_global_interative(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -290,6 +302,8 @@ fn cmd_global_interative(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_help(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
assert_noaddrs(s, cmd.linenums)?;
if (s.lasterror is Error) {
fmt::println(strerror(s.lasterror as Error))!;
@@ -297,6 +311,8 @@ fn cmd_help(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_helpmode(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
assert_noaddrs(s, cmd.linenums)?;
s.helpmode = !s.helpmode;
if (s.helpmode && s.lasterror is Error) {
@@ -305,6 +321,8 @@ fn cmd_helpmode(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_insert(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const n = get_linenum(cmd.linenums, s.buf.cursor);
const n = if (n == 0) 1z else n;
@@ -322,6 +340,8 @@ fn cmd_insert(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_join(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -356,6 +376,8 @@ fn cmd_join(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_mark(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const n = get_linenum(cmd.linenums, s.buf.cursor);
assert_nonzero(s, n)?;
@@ -393,6 +415,8 @@ fn cmd_mark(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_list(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -407,6 +431,8 @@ fn cmd_list(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_move(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -453,6 +479,8 @@ fn cmd_move(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_number(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -467,6 +495,8 @@ fn cmd_number(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_print(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -480,15 +510,28 @@ fn cmd_print(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_prompt(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
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 | Error) = {
+ if (s.buf.modified && !s.warned) {
+ s.warned = true;
+ return BufferModified;
+ };
-fn cmd_quit_forced(s: *Session, cmd: *Command) (void | Error) = void;
+ return Quit;
+};
+
+fn cmd_quit_forced(s: *Session, cmd: *Command) (void | Error) = {
+ return Quit;
+};
fn cmd_read(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const n = get_linenum(cmd.linenums, s.buf.cursor);
const fname = if (len(cmd.arg1) != 0) {
s.buf.filename = cmd.arg1;
@@ -512,6 +555,8 @@ fn cmd_read(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_substitute(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -558,6 +603,8 @@ fn cmd_substitute(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_copy(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -594,6 +641,8 @@ fn cmd_invglobal(s: *Session, cmd: *Command) (void | Error) = void;
fn cmd_invglobal_interative(s: *Session, cmd: *Command) (void | Error) = void;
fn cmd_write(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const (a, b) = get_range(
s,
&cmd.linenums,
@@ -634,11 +683,15 @@ fn cmd_write(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_linenumber(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const n = get_linenum(cmd.linenums, addr_lastline(s.buf));
fmt::println(n)!;
};
fn cmd_shellescape(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
let iter = strings::iter(cmd.arg1);
let new = memio::dynamic(); defer io::close(&new)!;
let preview = false;
@@ -703,6 +756,8 @@ fn cmd_shellescape(s: *Session, cmd: *Command) (void | Error) = {
};
fn cmd_null(s: *Session, cmd: *Command) (void | Error) = {
+ s.warned = false;
+
const n = get_linenum(
cmd.linenums,
addr_nextline(s.buf, s.buf.cursor),
diff --git a/interaction.ha b/interaction.ha
@@ -6,11 +6,14 @@ use strings;
use types;
type InteractionError = !(
- UnexpectedEOF
+ Quit
+ | UnexpectedEOF
| utf8::invalid
| io::error
);
+type Quit = !void;
+
type UnexpectedEOF = !io::EOF;
fn scanline(s: *Session) (str | InteractionError) = {
diff --git a/main.ha b/main.ha
@@ -96,16 +96,16 @@ export fn main() void = {
errormsg(&s, strerror(err));
continue;
};
+ defer command_finish(&cmd);
- // TODO: handle all ": void"s
- execute(&s, &cmd): void;
-
- debug("main(): before command_finish()");
- command_finish(&cmd);
- debug("main(): after command_finish()");
+ match (execute(&s, &cmd)) {
+ case Quit =>
+ debug("main() for match (exec) case Quit");
+ break;
+ case =>
+ void;
+ };
};
-
- // dumpbuffer(&s.buf);
};
fn exit_usage() never = {
@@ -114,11 +114,13 @@ fn exit_usage() never = {
};
fn errormsg(s: *Session, err: Error) void = {
+ if (err is Quit)
+ return;
+
fmt::errorln('?')!;
- let errmsg = strerror(err);
- if (s.helpmode) {
- fmt::errorfln(errmsg)!;
- };
+ if (s.helpmode)
+ fmt::errorfln(strerror(err))!;
+
s.lasterror = err;
};
@@ -127,6 +129,8 @@ fn strerror(err: Error) str = {
// InteractionError
case let e: InteractionError =>
match (e) {
+ case Quit =>
+ return "";
case UnexpectedEOF =>
return "Unexpected end-of-file input";
case let e: encoding::utf8::invalid =>