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:
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 = [