Skip to content

Commit b21eeaf

Browse files
committed
enhance undo/redo archiver
1 parent b8bcb7d commit b21eeaf

File tree

4 files changed

+129
-16
lines changed

4 files changed

+129
-16
lines changed

src/Data/History/archiver.cpp

Lines changed: 117 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ archiver_rep::confirm () {
330330
if (depth <= last_save) last_save= -1;
331331
if (depth <= last_autosave) last_autosave= -1;
332332
normalize ();
333-
// show_all ();
333+
show_all ();
334334
}
335335
}
336336
}
@@ -688,23 +688,131 @@ archiver_rep::reconstruct_from_state (tree old_state, tree new_state, path p, st
688688

689689
if (!trees_equal) {
690690
modification mod = compute_tree_diff(old_state, new_state, p, completion);
691+
cout << "modification: " << mod << LF;
692+
693+
//modification cursor_mod = compute_cursor_update(old_state, new_state, p, mod);
694+
//cout << "cursor modification: " << cursor_mod << LF;
695+
696+
the_et = old_state;
691697
add (mod);
692-
} else {
698+
the_et = new_state;
699+
//if (cursor_mod != mod_insert(path(), 0, "")) { // Check if cursor update is needed
700+
//add (cursor_mod);
701+
//}
693702
}
694703
confirm ();
695704
simplify ();
696705
}
697706

698707
modification
699708
archiver_rep::compute_tree_diff (tree old_tree, tree new_tree, path p, string completion) {
700-
// TODO: refactor
701709
cout << "compute_tree_diff: path=" << p << "\n";
702-
string old_s =as_string(subtree(old_tree, path_up(p, 1)));
710+
711+
string old_s = as_string(subtree(old_tree, path_up(p, 1)));
703712
string new_s = as_string(subtree(new_tree, path_up(p, 1)));
713+
714+
SI i = 0;
715+
SI j = 0;
716+
717+
// Find common prefix
718+
while (i < N(old_s) && i < N(new_s) && old_s[i] == new_s[i]) {
719+
i++;
720+
}
721+
722+
// Find common suffix (but don't overlap with prefix)
723+
while (j < (N(old_s) - i) && j < (N(new_s) - i) &&
724+
old_s[N(old_s) - 1 - j] == new_s[N(new_s) - 1 - j]) {
725+
j++;
726+
}
727+
728+
// Calculate the different parts
729+
SI old_start = i;
730+
SI old_end = N(old_s) - j;
731+
SI new_start = i;
732+
SI new_end = N(new_s) - j;
733+
734+
string old_diff = (old_end > old_start) ? old_s(old_start, old_end) : "";
735+
string new_diff = (new_end > new_start) ? new_s(new_start, new_end) : "";
736+
737+
cout << "old_s=\"" << old_s << "\", new_s=\"" << new_s << "\"\n";
738+
cout << "old_diff=\"" << old_diff << "\", new_diff=\"" << new_diff << "\"\n";
739+
cout << "prefix_len=" << i << ", suffix_len=" << j << "\n";
740+
704741
int insert_pos = last_item(p);
705-
string insert_content = completion;
706-
//cout << "compute_tree_diff: old_s=\"" << old_s << "\", new_s=\"" << new_s
707-
// << "\", insert_pos=" << insert_pos
708-
// << ", insert_content=\"" << insert_content << "\"\n";
709-
return mod_insert (path_up(p, 1), insert_pos, insert_content);
742+
743+
// Determine the operation based on the differences
744+
if (old_diff == "" && new_diff != "") {
745+
// Pure insertion
746+
cout << "Pure insertion detected\n";
747+
return mod_insert(path_up(p, 1), i, new_diff);
748+
}
749+
else if (old_diff != "" && new_diff == "") {
750+
// Pure deletion
751+
cout << "Pure deletion detected\n";
752+
// For deletion, the position should be relative to the new string
753+
// Since we deleted from old_start to old_end, the deletion position
754+
// in the context of the new string is at position i (common prefix length)
755+
return mod_remove(path_up(p, 1), i, N(old_diff));
756+
}
757+
else if (old_diff != "" && new_diff != "") {
758+
// Replacement (remove old, then insert new)
759+
// For simplicity, we'll use insert with the new content at position i
760+
cout << "Replacement detected, using insert\n";
761+
return mod_insert(path_up(p, 1), i, new_diff);
762+
}
763+
else {
764+
// No diff
765+
cout << "No difference detected\n";
766+
return mod_insert(path_up(p, 1), insert_pos, "");
767+
}
768+
}
769+
770+
modification
771+
archiver_rep::compute_cursor_update (tree old_tree, tree new_tree, path p, modification content_mod) {
772+
cout << "compute_cursor_update: path=" << p << ", content_mod=" << content_mod << "\n";
773+
int current_pos = last_item(p);
774+
int new_cursor_pos = current_pos;
775+
switch (content_mod->k) {
776+
case MOD_INSERT: {
777+
string inserted_text = as_string(content_mod->t);
778+
int insert_pos = last_item(content_mod->p);
779+
780+
if (current_pos >= insert_pos) {
781+
// Cursor was at or after the insertion point, move it forward
782+
new_cursor_pos = current_pos + N(inserted_text);
783+
}
784+
break;
785+
}
786+
787+
case MOD_REMOVE: {
788+
int remove_pos = last_item(path_up(content_mod->p, 1));
789+
int remove_count = last_item(content_mod->p);
790+
cout << "remove_pos=" << remove_pos << ", remove_count=" << remove_count << "\n";
791+
792+
if (current_pos > remove_pos + remove_count) {
793+
// Cursor was after the removed content, move it back
794+
new_cursor_pos = current_pos - remove_count;
795+
}
796+
else if (current_pos > remove_pos) {
797+
// Cursor was within the removed content, place it at the removal point
798+
new_cursor_pos = remove_pos;
799+
}
800+
break;
801+
}
802+
803+
default:
804+
break;
805+
}
806+
807+
cout << "cursor position: " << current_pos << " -> " << new_cursor_pos << "\n";
808+
809+
if (new_cursor_pos != current_pos) {
810+
path cursor_path = path_up(p, 1);
811+
// Create appropriate cursor data tree
812+
tree cursor_data = compound("author", "1");
813+
return mod_set_cursor(cursor_path, new_cursor_pos, cursor_data);
814+
}
815+
816+
// empty modification
817+
return mod_insert(path(), 0, "");
710818
}

src/Data/History/archiver.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class archiver_rep : public concrete_struct {
7373

7474
void reconstruct_from_state (tree old_state, tree new_state, path p, string completion);
7575
modification compute_tree_diff (tree old_tree, tree new_tree, path p, string completion);
76+
modification compute_cursor_update (tree old_tree, tree new_tree, path p, modification content_mod);
7677
bool is_content_modification (patch p);
7778

7879
inline void set_versioning (bool v) { versioning= v; }

src/Edit/Interface/edit_complete.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,14 @@ edit_interface_rep::complete_start (string prefix, array<string> compls) {
172172
set_arch_versioning (true);
173173
insert_tree (completions[0]);
174174

175+
if (get_input_mode() != INPUT_COMPLETE) {
176+
complete_et = copy (et);
177+
complete_tp = copy (tp);
178+
complete_str= completions[0];
179+
}
175180
complete_message ();
176181
// beep ();
177182
set_input_mode (INPUT_COMPLETE);
178-
complete_et = copy (et);
179-
complete_tp = copy (tp);
180-
complete_str= completions[0];
181183
}
182184
}
183185

@@ -186,7 +188,7 @@ edit_interface_rep::complete_keypress (string key) {
186188
int end = last_item (tp);
187189
string old_s= completions[completion_pos];
188190
string new_s= "";
189-
string test = completion_prefix * old_s;
191+
string full_s = completion_prefix * old_s;
190192
set_message ("", "");
191193
cout << "complete_keypress: " << key << LF;
192194
if (key == "space") key= " ";
@@ -204,11 +206,11 @@ edit_interface_rep::complete_keypress (string key) {
204206
SERVER (set_completion_popup_visible (false));
205207
return false;
206208
}
207-
//else if (key == "backspace" && N(completion_prefix) == 1) {
209+
//else if (key == "backspace" && N(full_s) == 1) {
208210
// complete_str = string("");
209211
// set_input_normal ();
210212
// SERVER (set_completion_popup_visible (false));
211-
// return false;
213+
// return true;
212214
//}
213215
else if ((key != "tab") && (key != "S-tab") && (key != "up") &&
214216
(key != "down")) {
@@ -224,7 +226,7 @@ edit_interface_rep::complete_keypress (string key) {
224226
set_input_normal ();
225227
return false;
226228
}
227-
if ((end < N (test)) || (s (end - N (test), end) != test)) {
229+
if ((end < N (full_s)) || (s (end - N (full_s), end) != full_s)) {
228230
set_input_normal ();
229231
return false;
230232
}
@@ -317,6 +319,7 @@ edit_interface_rep::custom_complete (tree r) {
317319
// cout << prefix << ", " << compls << LF;
318320

319321
if ((prefix == "") || (N (compls) <= 1)) {
322+
complete_str = string("");
320323
set_input_normal ();
321324
SERVER (set_completion_popup_visible (false));
322325
return;

src/Edit/Interface/edit_interface.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ edit_interface_rep::suspend () {
9292
set_message ("", "", false);
9393
}
9494
got_focus = false;
95+
set_input_normal ();
9596
env_change= env_change & (~THE_FREEZE);
9697
notify_change (THE_FOCUS);
9798
if (shadow != NULL) tm_delete (shadow);

0 commit comments

Comments
 (0)