ed

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

commit 76241273947303e26572921eb447a1a857f47d1c
parent c45768710a8a811b5111ef547cd956d19a4bf78c
Author: Byron Torres <b@torresjrjr.com>
Date:   Sun,  7 Jan 2024 21:44:26 +0000

add filename()

Diffstat:
Mbuffer.ha | 2++
Mcommand.ha | 64++++++++++++++--------------------------------------------------
Mmain.ha | 4++--
Mutil.ha | 12++++++++++++
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; +};