commit 76241273947303e26572921eb447a1a857f47d1c
parent c45768710a8a811b5111ef547cd956d19a4bf78c
Author: Byron Torres <b@torresjrjr.com>
Date: Sun, 7 Jan 2024 21:44:26 +0000
add filename()
Diffstat:
4 files changed, 30 insertions(+), 52 deletions(-)
diff --git a/buffer.ha b/buffer.ha
@@ -94,7 +94,9 @@ 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)
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
@@ -34,7 +34,7 @@ type CmdError = !(
| UnexpectedAddress
| InvalidDestination
| NoFilename
- | BufferModified
+ | WarnBufferModified
| NoMatch
| NoPrevShCmd
| NoPrevGlobalSubCmd
@@ -49,7 +49,7 @@ type InvalidDestination = !void;
type NoFilename = !void;
-type BufferModified = !void;
+type WarnBufferModified = !void;
type NoPrevShCmd = !void;
@@ -182,19 +182,10 @@ fn cmd_edit(s: *Session, cmd: *Command) (void | Error) = {
if (s.buf.modified && !s.warned) {
s.warned = true;
- return BufferModified;
+ return WarnBufferModified;
};
- const fname =
- if (len(cmd.arg1) != 0) {
- s.buf.filename = strings::dup(cmd.arg1);
- yield cmd.arg1;
- } else if (len(s.buf.filename) != 0) {
- yield s.buf.filename;
- } else {
- return NoFilename;
- };
-
+ const fname = filename(s, cmd, true)?;
const h = os::open(fname)?; defer io::close(h)!;
buf_deleteall(s.buf);
@@ -209,16 +200,7 @@ fn cmd_edit(s: *Session, cmd: *Command) (void | Error) = {
fn cmd_edit_forced(s: *Session, cmd: *Command) (void | Error) = {
assert_noaddrs(s, cmd.linenums)?;
- const fname =
- if (len(cmd.arg1) != 0) {
- s.buf.filename = strings::dup(cmd.arg1);
- yield cmd.arg1;
- } else if (len(s.buf.filename) != 0) {
- yield s.buf.filename;
- } else {
- return NoFilename;
- };
-
+ const fname = filename(s, cmd, true)?;
const h = os::open(fname)?; defer io::close(h)!;
buf_deleteall(s.buf);
@@ -235,13 +217,8 @@ fn cmd_filename(s: *Session, cmd: *Command) (void | Error) = {
assert_noaddrs(s, cmd.linenums)?;
- if (cmd.arg1 != "")
- s.buf.filename = strings::dup(cmd.arg1);
-
- if (s.buf.filename == "")
- return NoFilename;
-
- fmt::println(s.buf.filename)!;
+ const fname = filename(s, cmd, true)?;
+ fmt::println(fname)!;
};
fn cmd_global(s: *Session, cmd: *Command) (void | Error) = {
@@ -455,7 +432,7 @@ fn cmd_prompt(s: *Session, cmd: *Command) (void | Error) = {
fn cmd_quit(s: *Session, cmd: *Command) (void | Error) = {
if (s.buf.modified && !s.warned) {
s.warned = true;
- return BufferModified;
+ return WarnBufferModified;
};
return Quit;
@@ -469,16 +446,8 @@ 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;
- yield cmd.arg1;
- } else if (len(s.buf.filename) != 0) {
- yield s.buf.filename;
- } else {
- return NoFilename;
- };
+ const fname = filename(s, cmd, false)?;
const h = os::open(fname)?: io::handle;
defer io::close(h)!;
@@ -594,16 +563,7 @@ fn cmd_write(s: *Session, cmd: *Command) (void | Error) = {
)?;
assert_nonzero(s, a)?;
- const fname =
- if (len(cmd.arg1) != 0) {
- s.buf.filename = strings::dup(cmd.arg1);
- yield s.buf.filename;
- } else if (len(s.buf.filename) != 0) {
- yield s.buf.filename;
- } else {
- return NoFilename;
- };
-
+ const fname = filename(s, cmd, false)?;
const h = match (os::open(fname, fs::flag::WRONLY)) {
case let err: fs::error =>
yield match (err) {
@@ -621,6 +581,10 @@ fn cmd_write(s: *Session, cmd: *Command) (void | Error) = {
if (!s.suppressmode)
fmt::println(sz)!;
+
+ if (a == 1 && b == len(s.buf.lines))
+ // the entier buffer has been written.
+ s.buf.modified = false;
};
fn cmd_linenumber(s: *Session, cmd: *Command) (void | Error) = {
diff --git a/main.ha b/main.ha
@@ -151,8 +151,8 @@ fn strerror(err: Error) str = {
return "Invalid address";
case NoFilename =>
return "No filename";
- case BufferModified =>
- return "Buffer modified";
+ case WarnBufferModified =>
+ return "Warning: Buffer modified";
case UnexpectedAddress =>
return "Unexpected address";
case InvalidDestination =>
diff --git a/util.ha b/util.ha
@@ -82,3 +82,15 @@ fn printlistln(text: str) (size | io::error) = {
sz += fmt::println('$')?;
return sz;
};
+
+fn filename(s: *Session, cmd: *Command, remember: bool) (str | NoFilename) = {
+ if (cmd.arg1 != "") {
+ if (remember || s.buf.filename == "")
+ s.buf.filename = strings::dup(cmd.arg1);
+ return cmd.arg1;
+ };
+ if (s.buf.filename != "")
+ return s.buf.filename;
+
+ return NoFilename;
+};