aboutsummaryrefslogtreecommitdiff
path: root/vis-marks.c
diff options
context:
space:
mode:
authorRandy Palamar <randy@rnpnr.xyz>2025-12-17 16:29:06 -0700
committerRandy Palamar <randy@rnpnr.xyz>2026-01-06 15:38:58 -0700
commit65d0847af82ba6189817dfab4485de111e299634 (patch)
treed4e0d5a3a80a081785445d6d5e5c0adcc7ac3bc2 /vis-marks.c
parent9f133c83126c77b05b18e3b3def8a9394d6b42f9 (diff)
downloadvis-65d0847af82ba6189817dfab4485de111e299634.tar.gz
vis-65d0847af82ba6189817dfab4485de111e299634.tar.xz
vis-marks: greatly simplify jumplist management
As far as I could tell from the code this was supposed to be a fixed size LRU cache of sets of selection regions. The structure had a maximum size member but it was never set or used. Furthermore there was some very complicated management of 2 parallel sets of regions. Instead of that mess just treat the cache as a circular buffer. Note that this is really not that useful at the moment. While the selection regions are saved and restored the editor mode is not. Therefore the selection is visible but not in any way usable. That will be fixed in the next commit.
Diffstat (limited to 'vis-marks.c')
-rw-r--r--vis-marks.c108
1 files changed, 27 insertions, 81 deletions
diff --git a/vis-marks.c b/vis-marks.c
index 6d63877..a44e727 100644
--- a/vis-marks.c
+++ b/vis-marks.c
@@ -104,115 +104,61 @@ void vis_mark_set(Win *win, enum VisMark id, Array *sel) {
mark_set(win, mark_from(win->vis, id), sel);
}
-void marklist_init(MarkList *list, size_t max) {
- Array mark;
- mark_init(&mark);
- array_init_sized(&list->prev, sizeof(Array));
- array_reserve(&list->prev, max);
- array_add(&list->prev, &mark);
- array_init_sized(&list->next, sizeof(Array));
- array_reserve(&list->next, max);
-}
-
-void marklist_release(MarkList *list) {
- for (size_t i = 0, len = list->prev.len; i < len; i++)
- array_release(array_get(&list->prev, i));
- array_release(&list->prev);
- for (size_t i = 0, len = list->next.len; i < len; i++)
- array_release(array_get(&list->next, i));
- array_release(&list->next);
-}
-
-static bool marklist_push(Win *win, MarkList *list, Array *sel) {
- Array *top = array_peek(&list->prev);
- if (top) {
+void vis_jumplist_save(Vis *vis)
+{
+ Win *win = vis->win;
+ Array sel = view_selections_get_all(&win->view);
+ Array *top = win->mark_set_lru + (win->mark_set_lru_cursor % LENGTH(win->mark_set_lru));
+ bool done = false;
+ if (top->len) {
Array top_sel = mark_get(win, top);
- bool eq = vis_mark_equal(&top_sel, sel);
+ /* NOTE: avoid pushing duplicate sets into cache */
+ done = vis_mark_equal(&top_sel, &sel);
array_release(&top_sel);
- if (eq)
- return true;
}
- for (size_t i = 0, len = list->next.len; i < len; i++)
- array_release(array_get(&list->next, i));
- array_clear(&list->next);
- Array arr;
- mark_init(&arr);
- if (list->prev.len >= list->prev.count) {
- Array *tmp = array_get(&list->prev, 0);
- arr = *tmp;
- array_remove(&list->prev, 0);
+ if (!done) {
+ Array *arr = win->mark_set_lru + (win->mark_set_lru_cursor++ % LENGTH(win->mark_set_lru));
+ mark_set(win, arr, &sel);
}
- mark_set(win, &arr, sel);
- return array_push(&list->prev, &arr);
-}
-bool vis_jumplist_save(Vis *vis) {
- Array sel = view_selections_get_all(&vis->win->view);
- bool ret = marklist_push(vis->win, &vis->win->jumplist, &sel);
array_release(&sel);
- return ret;
}
-static bool marklist_prev(Win *win, MarkList *list) {
+void vis_jumplist_prev(Vis *vis)
+{
+ Win *win = vis->win;
View *view = &win->view;
- bool restore = false;
Array cur = view_selections_get_all(view);
bool anchored = view_selections_primary_get(view)->anchored;
- Array *top = array_peek(&list->prev);
- if (!top)
- goto out;
- Array top_sel = mark_get(win, top);
- restore = !vis_mark_equal(&top_sel, &cur);
- if (restore)
- view_selections_set_all(view, &top_sel, anchored);
- array_release(&top_sel);
- if (restore)
- goto out;
-
- while (list->prev.len > 1) {
- Array *prev = array_pop(&list->prev);
- array_push(&list->next, prev);
- prev = array_peek(&list->prev);
- Array sel = mark_get(win, prev);
- restore = sel.len > 0;
- if (restore)
+
+ Array *top = win->mark_set_lru + (--win->mark_set_lru_cursor % LENGTH(win->mark_set_lru));
+ if (top->len) {
+ Array sel = mark_get(win, top);
+ if (!vis_mark_equal(top, &cur)) {
view_selections_set_all(view, &sel, anchored);
+ }
array_release(&sel);
- if (restore)
- goto out;
}
-out:
array_release(&cur);
- return restore;
}
-static bool marklist_next(Win *win, MarkList *list) {
+void vis_jumplist_next(Vis *vis)
+{
+ Win *win = vis->win;
View *view = &win->view;
bool anchored = view_selections_primary_get(view)->anchored;
- for (;;) {
- Array *next = array_pop(&list->next);
- if (!next)
- return false;
+ Array *next = win->mark_set_lru + (win->mark_set_lru_cursor++ % LENGTH(win->mark_set_lru));
+
+ if (next->len) {
Array sel = mark_get(win, next);
if (sel.len > 0) {
view_selections_set_all(view, &sel, anchored);
array_release(&sel);
- array_push(&list->prev, next);
- return true;
}
- array_release(next);
}
}
-bool vis_jumplist_prev(Vis *vis) {
- return marklist_prev(vis->win, &vis->win->jumplist);
-}
-
-bool vis_jumplist_next(Vis *vis) {
- return marklist_next(vis->win, &vis->win->jumplist);
-}
-
enum VisMark vis_mark_from(Vis *vis, char mark) {
if (mark >= 'a' && mark <= 'z')
return VIS_MARK_a + mark - 'a';