From 6ced61ef5f366001877823ed8aff978035fa53c8 Mon Sep 17 00:00:00 2001 From: Randy Palamar Date: Wed, 17 Dec 2025 17:19:10 -0700 Subject: vis-marks: make mark set cache actually useful Without also saving and restoring the editor mode when the selections were added to the cache almost no useful actions can be performed. While we are at it the 3 jumplist functions can just be combined into one. --- main.c | 7 +------ vis-core.h | 15 +++++++++++--- vis-marks.c | 66 +++++++++++++++++++++---------------------------------------- vis.c | 8 ++++---- vis.h | 14 +++++-------- 5 files changed, 45 insertions(+), 65 deletions(-) diff --git a/main.c b/main.c index e336916..1aade34 100644 --- a/main.c +++ b/main.c @@ -1247,12 +1247,7 @@ static KEY_ACTION_FN(ka_percent) static KEY_ACTION_FN(ka_jumplist) { - if (arg->i < 0) - vis_jumplist_prev(vis); - else if (arg->i > 0) - vis_jumplist_next(vis); - else - vis_jumplist_save(vis); + vis_jumplist(vis, arg->i); return keys; } diff --git a/vis-core.h b/vis-core.h index 6e601ab..82e684a 100644 --- a/vis-core.h +++ b/vis-core.h @@ -161,9 +161,18 @@ struct Win { Mode *parent_mode; /* mode which was active when showing the command prompt */ Win *prev, *next; /* neighbouring windows */ - /* Jumplist LRU */ - size_t mark_set_lru_cursor; - Array mark_set_lru[32]; + /* NOTE: Selection Jump Cache + * Anytime the selection jumps the previous set of selections gets + * pushed into this cache. The user can navigate this cache to + * restore old selections and they can save their own selection + * sets into the cache. + * + * IMPORTANT: cursor is not kept in bounds. it is always used modulo VIS_MARK_SET_LRU_COUNT + */ + #define VIS_MARK_SET_LRU_COUNT (32) + size_t mark_set_lru_cursor; + Array mark_set_lru_regions[VIS_MARK_SET_LRU_COUNT]; + enum VisMode mark_set_lru_modes[VIS_MARK_SET_LRU_COUNT]; }; struct Vis { diff --git a/vis-marks.c b/vis-marks.c index a44e727..083d331 100644 --- a/vis-marks.c +++ b/vis-marks.c @@ -104,59 +104,39 @@ void vis_mark_set(Win *win, enum VisMark id, Array *sel) { mark_set(win, mark_from(win->vis, id), sel); } -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); - /* NOTE: avoid pushing duplicate sets into cache */ - done = vis_mark_equal(&top_sel, &sel); - array_release(&top_sel); - } - - if (!done) { - Array *arr = win->mark_set_lru + (win->mark_set_lru_cursor++ % LENGTH(win->mark_set_lru)); - mark_set(win, arr, &sel); - } - - array_release(&sel); -} - -void vis_jumplist_prev(Vis *vis) +void vis_jumplist(Vis *vis, int advance) { Win *win = vis->win; View *view = &win->view; Array cur = view_selections_get_all(view); - bool anchored = view_selections_primary_get(view)->anchored; - 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); - } - array_release(&cur); -} - -void vis_jumplist_next(Vis *vis) -{ - Win *win = vis->win; - View *view = &win->view; - bool anchored = view_selections_primary_get(view)->anchored; - Array *next = win->mark_set_lru + (win->mark_set_lru_cursor++ % LENGTH(win->mark_set_lru)); + size_t cursor = win->mark_set_lru_cursor; + win->mark_set_lru_cursor += advance; + if (advance < 0) + cursor = win->mark_set_lru_cursor; + cursor %= VIS_MARK_SET_LRU_COUNT; + Array *next = win->mark_set_lru_regions + cursor; + bool done = false; if (next->len) { Array sel = mark_get(win, next); - if (sel.len > 0) { - view_selections_set_all(view, &sel, anchored); - array_release(&sel); + done = vis_mark_equal(&sel, &cur); + if (advance && !done) { + /* NOTE: set cached selection */ + vis_mode_switch(vis, win->mark_set_lru_modes[cursor]); + view_selections_set_all(view, &sel, view_selections_primary_get(view)->anchored); } + array_release(&sel); + } + + if (!advance && !done) { + /* NOTE: save the current selection */ + mark_set(win, next, &cur); + win->mark_set_lru_modes[cursor] = vis->mode->id; + win->mark_set_lru_cursor++; } + + array_release(&cur); } enum VisMark vis_mark_from(Vis *vis, char mark) { diff --git a/vis.c b/vis.c index d38b367..5b5ce2f 100644 --- a/vis.c +++ b/vis.c @@ -204,8 +204,8 @@ static void window_free(Win *win) { view_free(&win->view); for (size_t i = 0; i < LENGTH(win->modes); i++) map_free(win->modes[i].bindings); - for (int i = 0; i < LENGTH(win->mark_set_lru); i++) - free(win->mark_set_lru[i].items); + for (int i = 0; i < VIS_MARK_SET_LRU_COUNT; i++) + free(win->mark_set_lru_regions[i].items); mark_release(&win->saved_selections); free(win); } @@ -385,8 +385,8 @@ Win *window_new_file(Vis *vis, File *file, enum UiOption options) { return NULL; } - for (int i = 0; i < LENGTH(win->mark_set_lru); i++) - win->mark_set_lru[i].elem_size = sizeof(SelectionRegion); + for (int i = 0; i < VIS_MARK_SET_LRU_COUNT; i++) + win->mark_set_lru_regions[i].elem_size = sizeof(SelectionRegion); mark_init(&win->saved_selections); file->refcount++; diff --git a/vis.h b/vis.h index 272df07..72f6ec5 100644 --- a/vis.h +++ b/vis.h @@ -957,20 +957,16 @@ VIS_EXPORT Array vis_mark_get(Win *win, enum VisMark id); */ VIS_EXPORT void vis_mark_normalize(Array *array); /** - * Add selections of focused window to jump list. + * Add selections of focused window to jump list. Equivalent to vis_jumplist(vis, 0). * @param vis The editor instance. */ -VIS_EXPORT void vis_jumplist_save(Vis*); +#define vis_jumplist_save(vis) vis_jumplist((vis), 0) /** - * Navigate jump list backwards. + * Navigate jump list by a specified amount. Wraps if advance exceeds list size. * @param vis The editor instance. + * @param advance The amount to advance the cursor by. 0 saves the current selections. */ -VIS_EXPORT void vis_jumplist_prev(Vis*); -/** - * Navigate jump list forwards. - * @param vis The editor instance. - */ -VIS_EXPORT void vis_jumplist_next(Vis*); +VIS_EXPORT void vis_jumplist(Vis *, int advance); /** @} */ /* -- cgit v1.2.3