diff options
| author | Randy Palamar <randy@rnpnr.xyz> | 2025-12-17 17:19:10 -0700 |
|---|---|---|
| committer | Randy Palamar <randy@rnpnr.xyz> | 2026-01-06 15:54:04 -0700 |
| commit | 6ced61ef5f366001877823ed8aff978035fa53c8 (patch) | |
| tree | 23487e77c00326e6fca9bb31beb4aff0ede92f14 | |
| parent | 65d0847af82ba6189817dfab4485de111e299634 (diff) | |
| download | vis-6ced61ef5f366001877823ed8aff978035fa53c8.tar.gz vis-6ced61ef5f366001877823ed8aff978035fa53c8.tar.xz | |
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.
| -rw-r--r-- | main.c | 7 | ||||
| -rw-r--r-- | vis-core.h | 15 | ||||
| -rw-r--r-- | vis-marks.c | 66 | ||||
| -rw-r--r-- | vis.c | 8 | ||||
| -rw-r--r-- | vis.h | 14 |
5 files changed, 45 insertions, 65 deletions
@@ -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; } @@ -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) { @@ -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++; @@ -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); /** @} */ /* |
