ed

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

commit 1f848b072e8fa9752be851da1f6b2fa5c2cecb47
parent 88cd4e19d8f90212946de3caa7f172e9625c8d31
Author: Byron Torres <b@torresjrjr.com>
Date:   Mon, 22 Jan 2024 23:11:31 +0000

add hist_tidy(); fix redo

Diffstat:
Maddress.ha | 4++--
Mbuffer.ha | 14++++++++++++--
Mcommand.ha | 44++++++++++++++++++++++++++------------------
Mexecute.ha | 10++++++++++
Mhistory.ha | 21+++++++++++++++++----
Mmain.ha | 1-
6 files changed, 67 insertions(+), 27 deletions(-)

diff --git a/address.ha b/address.ha @@ -92,8 +92,8 @@ fn addr_regex( }; fn newregex(s: *Session, expr: str) (regex::regex | NoPrevRegex | regex::error) = { - debug("expr=<{}>", expr); - debug("s.lastregex=<{}>", s.lastregex); + //debug("expr=<{}>", expr); + //debug("s.lastregex=<{}>", s.lastregex); const newexpr = if (expr != "") diff --git a/buffer.ha b/buffer.ha @@ -12,6 +12,7 @@ type Buffer = struct{ cursor: size, modified: bool, written: bool, + redolastchange: bool, }; type Line = struct{ @@ -38,7 +39,7 @@ fn buf_insert(buf: *Buffer, n: size, ls: *Line...) void = { hist_append(buf, (n, len(ls)): Addition); - debug("buf_insert(): len('last changeseq')={}", len(buf.hist[len(buf.hist) - 1])); +// debug("buf_insert(): len('last changeseq')={}", len(buf.hist[len(buf.hist) - 1])); }; fn buf_deleteall(buf: *Buffer) void = { @@ -61,7 +62,7 @@ fn buf_delete(buf: *Buffer, a: size, b: size) void = { hist_append(buf, (a, (b + 1 - a)): Deletion); - debug("buf_delete(): len('last changeseq')={}", len(buf.hist[len(buf.hist) - 1])); +// debug("buf_delete(): len('last changeseq')={}", len(buf.hist[len(buf.hist) - 1])); }; fn buf_read( @@ -113,3 +114,12 @@ fn buf_wipetrash(buf: *Buffer) void = { }; delete(buf.trash[..]); }; + +fn buf_prunetrash(buf: *Buffer, keep: size) void = { + let upto = len(buf.trash) - keep; + for (let i = 0z; i < upto; i += 1) { + free(buf.trash[i].text); + free(buf.trash[i]); + }; + delete(buf.trash[ ..upto ]); +}; diff --git a/command.ha b/command.ha @@ -121,16 +121,17 @@ fn cmd_append(s: *Session, cmd: *Command) (void | Error) = { const n = get_linenum(cmd.linenums, s.buf.cursor); - if (len(cmd.textinput) > 0) { + if (len(cmd.textinput) > 0) hist_newseq(s.buf); - s.redolastchange = false; - }; for (let i = 0z; i < len(cmd.textinput); i += 1) { const line = alloc(Line{ text = cmd.textinput[i], ... }); buf_insert(s.buf, n + 1 + i, line); }; + if (len(cmd.textinput) > 0) + hist_tidy(s, s.buf, 0); + s.buf.cursor = n + len(cmd.textinput); printmode(s, cmd)?; }; @@ -151,8 +152,10 @@ fn cmd_change(s: *Session, cmd: *Command) (void | Error) = { }; }; - hist_newseq(s.buf); s.redolastchange = false; + hist_newseq(s.buf); buf_delete(s.buf, a, b); + hist_tidy(s, s.buf, b - a + 1); + for (let i = 0z; i < len(cmd.textinput); i += 1) { const line = alloc(Line{ text = cmd.textinput[i], ... }); @@ -181,8 +184,9 @@ fn cmd_delete(s: *Session, cmd: *Command) (void | Error) = { )?; assert_nonzero(s, a)?; - hist_newseq(s.buf); s.redolastchange = false; + hist_newseq(s.buf); buf_delete(s.buf, a, b); + hist_tidy(s, s.buf, b - a + 1); s.buf.cursor = if (len(s.buf.lines) == 1) @@ -248,16 +252,17 @@ fn cmd_insert(s: *Session, cmd: *Command) (void | Error) = { const n = get_linenum(cmd.linenums, s.buf.cursor); const n = if (n == 0) 1z else n; - if (len(cmd.textinput) > 0) { + if (len(cmd.textinput) > 0) hist_newseq(s.buf); - s.redolastchange = false; - }; for (let i = 0z; i < len(cmd.textinput); i += 1) { const line = alloc(Line{ text = cmd.textinput[i], ... }); buf_insert(s.buf, n + i, line); }; + if (len(cmd.textinput) > 0) + hist_tidy(s, s.buf, 0); + s.buf.cursor = if (len(cmd.textinput) == 0) n @@ -295,9 +300,10 @@ fn cmd_join(s: *Session, cmd: *Command) (void | Error) = { ... }); - hist_newseq(s.buf); s.redolastchange = false; + hist_newseq(s.buf); buf_delete(s.buf, a, b); buf_insert(s.buf, a, newline); + hist_tidy(s, s.buf, b - a + 1); s.buf.cursor = a; printmode(s, cmd)?; @@ -387,9 +393,10 @@ fn cmd_move(s: *Session, cmd: *Command) (void | Error) = { const lines = alloc(s.buf.lines[a..b+1]...); defer free(lines); // TODO: mem? - hist_newseq(s.buf); s.redolastchange = false; + hist_newseq(s.buf); buf_delete(s.buf, a, b); buf_insert(s.buf, dest, lines...); + hist_tidy(s, s.buf, b - a + 1); s.buf.cursor = dest - 1 + len(lines); printmode(s, cmd)?; @@ -472,12 +479,12 @@ fn cmd_read(s: *Session, cmd: *Command) (void | Error) = { hist_newseq(s.buf); - const (sz, _) = buf_read(s.buf, rd, n)?; + const (sz, linecnt) = buf_read(s.buf, rd, n)?; - if (sz == 0) + if (linecnt == 0) hist_discardseq(s.buf) else - s.redolastchange = false; + hist_tidy(s, s.buf, 0); if (!s.suppressmode) fmt::println(sz)!; @@ -556,7 +563,7 @@ fn cmd_substitute(s: *Session, cmd: *Command) (void | Error) = { hist_discardseq(s.buf); return NoMatch; } else { - s.redolastchange = false; + hist_tidy(s, s.buf, changes); }; printmode(s, cmd)?; @@ -590,8 +597,9 @@ fn cmd_copy(s: *Session, cmd: *Command) (void | Error) = { const lines = alloc(s.buf.lines[a..b+1]...); defer free(lines); // TODO: ? - hist_newseq(s.buf); s.redolastchange = false; + hist_newseq(s.buf); buf_insert(s.buf, dest, lines...); + hist_tidy(s, s.buf, 0); s.buf.cursor = dest - 1 + len(lines); printmode(s, cmd)?; @@ -604,12 +612,12 @@ fn cmd_undo(s: *Session, cmd: *Command) (void | Error) = { switch (s.undomode) { case UndoMode::POSIX => - if (s.redolastchange) { + if (s.buf.redolastchange) { hist_redo(s.buf)?; - s.redolastchange = false; + s.buf.redolastchange = false; } else { hist_undo(s.buf)?; - s.redolastchange = true; + s.buf.redolastchange = true; }; case UndoMode::FULL => hist_undo(s.buf)?; diff --git a/execute.ha b/execute.ha @@ -13,6 +13,16 @@ fn execute(s: *Session, cmd: *Command) (void | Error) = { return e; }; + if (len(s.buf.hist) > 0) { + let cseq = s.buf.hist[len(s.buf.hist) - 1]; + for (let i = 0z; i < len(cseq); i += 1) + match (cseq[i]) { + case let addn: Addition => + debug("cseq[{}]=Addition({}, {})", i, addn.0, addn.1); + case let deln: Deletion => + debug("cseq[{}]=Deletion({}, {})", i, deln.0, deln.1); + }; + }; for (let i = 0z; i < len(s.buf.trash); i += 1) debug("trash[{}]={}", i, s.buf.trash[i].text); }; diff --git a/history.ha b/history.ha @@ -27,6 +27,9 @@ fn hist_clear(buf: *Buffer) void = { }; fn hist_newseq(buf: *Buffer) void = { + if (buf.redolastchange) + delete(buf.hist[ len(buf.hist) - 1 ]); + append(buf.hist, []: ChangeSeq); }; @@ -39,6 +42,14 @@ fn hist_append(buf: *Buffer, change: Change) void = { append(buf.hist[len(buf.hist) - 1], change); }; +fn hist_tidy(s: *Session, buf: *Buffer, cmd_deletions: size) void = { + if (s.undomode == UndoMode::POSIX) { + buf_prunetrash(buf, cmd_deletions); + // TODO: prune history + }; + s.buf.redolastchange = false; +}; + fn hist_undo(buf: *Buffer) (void | NoHistory) = { debug("hist_undo()"); if (len(buf.hist) == 0) @@ -69,14 +80,16 @@ fn hist_redo(buf: *Buffer) (void | NoHistory) = { let seq = buf.hist[ len(buf.hist) - 1 ]; - for (let j = len(seq) - 1; j < len(seq); j -= 1) - match (seq[j]) { + for (let i = 0z; i < len(seq); i += 1) + match (seq[i]) { case let addn: Addition => let (n, m) = addn; let lentrash = len(buf.trash); - let lines = buf.trash[(lentrash - m)..]; + //let lines = buf.trash[(lentrash - m)..]; + let lines = buf.trash[..m]; insert(buf.lines[n], lines...); - delete(buf.trash[(lentrash - m)..]); + //delete(buf.trash[(lentrash - m)..]); + delete(buf.trash[..m]); case let deln: Deletion => let (n, m) = deln; let lines = buf.lines[n..(n + m)]; diff --git a/main.ha b/main.ha @@ -20,7 +20,6 @@ type Session = struct{ lasterror: (void | Error), lastregex: (void | str), lastshcmd: (void | str), - redolastchange: bool, }; def proghelp: [_]getopt::help = [