[PATCH ed v2] hist: reset cursor following POSIX
Export this patch
Signed-off-by: Curtis Arthaud <uku82@gmx.fr>
---
I incorporated the idea I mentioned earlier.
Seems to fix things nicely?
buffer.ha | 6 +++ ---
command.ha | 3 +++
history.ha | 40 ++++++++++++++++++++++++++ --------------
3 files changed, 32 insertions(+), 17 deletions(-)
diff --git a/buffer.ha b/buffer.ha
index a32216f..c0b40c6 100644
--- a/buffer.ha
@@ -35,7 +35,7 @@ fn buf_insert(buf: *Buffer, n: size, ls: *Line...) void = {
buf.modified = true;
- hist_append(buf, (n, len(ls)): Addition);
+ hist_append(buf, (n, len(ls), buf.cursor): Addition);
// debug("buf_insert(): len('last changeseq')={}", len(buf.hist[len(buf.hist) - 1]));
};
@@ -56,7 +56,7 @@ fn buf_delete(buf: *Buffer, a: size, b: size) void = {
buf.modified = true;
- hist_append(buf, (a, (b + 1 - a)): Deletion);
+ hist_append(buf, (a, (b + 1 - a), buf.cursor): Deletion);
// debug("buf_delete(): len('last changeseq')={}", len(buf.hist[len(buf.hist) - 1]));
};
@@ -85,7 +85,7 @@ fn buf_read(
insert(buf.lines[n + 1], lines...);
- hist_append(buf, (n + 1, m): Addition);
+ hist_append(buf, (n + 1, m, buf.cursor): Addition);
buf.modified = true;
diff --git a/command.ha b/command.ha
index 62d24ef..cf65730 100644
--- a/command.ha
+++ b/command.ha
@@ -616,11 +616,14 @@ fn cmd_undo(s: *Session, cmd: *Command) (void | Error) = {
switch (s.undomode) {
case UndoMode::POSIX =>
+ const cur = s.buf.cursor;
if (s.buf.redolastchange) {
hist_redo(s.buf)?;
+ hist_reset_undo_cursor(s.buf, cur);
s.buf.redolastchange = false;
} else {
hist_undo(s.buf)?;
+ hist_reset_undo_cursor(s.buf, cur);
s.buf.redolastchange = true;
};
case UndoMode::FULL =>
diff --git a/history.ha b/history.ha
index ea109a2..bacae82 100644
--- a/history.ha
+++ b/history.ha
@@ -7,11 +7,11 @@ type ChangeSeq = []Change;
// A record of a single arbitrary buffer change.
type Change = (Addition | Deletion);
- // The addition of a buffer chunk (start position, chunk size).
- type Addition = (size, size);
+ // The addition of a buffer chunk (start position, chunk size, cursor).
+ type Addition = (size, size, size);
- // The deletion of a buffer chunk (start position, chunk size).
- type Deletion = (size, size);
+ // The deletion of a buffer chunk (start position, chunk size, cursor).
+ type Deletion = (size, size, size);
// The effect of the undo command.
type UndoMode = enum{
@@ -60,19 +60,18 @@ fn hist_undo(buf: *Buffer) (void | NoHistory) = {
for (let j = len(seq) - 1; j < len(seq); j -= 1)
match (seq[j]) {
case let deln: Deletion =>
- let (n, m) = deln;
+ let (n, m, cur) = deln;
let lentrash = len(buf.trash);
let lines = buf.trash[(lentrash - m)..];
insert(buf.lines[n], lines...);
delete(buf.trash[(lentrash - m)..]);
- buf.cursor = (n + m) - 1;
+ buf.cursor = cur;
case let addn: Addition =>
- let (n, m) = addn;
+ let (n, m, cur) = addn;
let lines = buf.lines[n..(n + m)];
insert(buf.trash[0], lines...);
delete(buf.lines[n..(n + m)]);
- let prev = addr_prevline(buf, n);
- buf.cursor = prev;
+ buf.cursor = cur;
};
};
@@ -86,20 +85,33 @@ fn hist_redo(buf: *Buffer) (void | NoHistory) = {
for (let i = 0z; i < len(seq); i += 1)
match (seq[i]) {
case let addn: Addition =>
- let (n, m) = addn;
+ let (n, m, cur) = addn;
//let lentrash = len(buf.trash);
//let lines = buf.trash[(lentrash - m)..];
let lines = buf.trash[..m];
insert(buf.lines[n], lines...);
//delete(buf.trash[(lentrash - m)..]);
delete(buf.trash[..m]);
- buf.cursor = (n + m) - 1;
+ buf.cursor = cur;
case let deln: Deletion =>
- let (n, m) = deln;
+ let (n, m, cur) = deln;
let lines = buf.lines[n..(n + m)];
append(buf.trash, lines...);
delete(buf.lines[n..(n + m)]);
- let prev = addr_prevline(buf, n);
- buf.cursor = prev;
+ buf.cursor = cur;
+ };
+ };
+
+ fn hist_reset_undo_cursor(buf: *Buffer, cur: size) void = {
+ const seq = buf.hist[ len(buf.hist) - 1 ];
+ hist_newseq(buf);
+ for (let i = 0z; i < len(seq); i += 1)
+ match (seq[i]) {
+ case let addn: Addition =>
+ let (n, m, c) = addn;
+ hist_append(buf, (n, m, cur): Addition);
+ case let deln: Deletion =>
+ let (n, m, c) = deln;
+ hist_append(buf, (n, m, cur): Deletion);
};
};
--
Adding a duplicate ChangeSeq with different cursors? I don't get it.
This is too confusing and hacky. You're changing the history.
It has become apparent to me that we need to redesign the history.
2.44.0
I'm thinking something like:
type Change = (Addition | Deletion | CursorMove);
type CursorMove = (size, size); // (before, after)
fn buf_updatecursor(buf: *Buffer, cur: size) void = {
hist_append(buf, (buf.cursor, cur): CursorMove)
};
s/s.buf.cursor =/buf_updatecursor(/ # where appropriate
Though these changes would require some thought.