aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--array.c18
-rw-r--r--array.h21
-rw-r--r--test/core/array-test.c8
-rw-r--r--vis-core.h14
-rw-r--r--vis-marks.c108
-rw-r--r--vis.c8
-rw-r--r--vis.h6
7 files changed, 41 insertions, 142 deletions
diff --git a/array.c b/array.c
index a6de4b1..e60b78e 100644
--- a/array.c
+++ b/array.c
@@ -141,21 +141,3 @@ void array_sort(Array *arr, int (*compar)(const void*, const void*)) {
if (arr->items)
qsort(arr->items, arr->len, arr->elem_size, compar);
}
-
-bool array_push(Array *arr, void *item) {
- return array_add(arr, item);
-}
-
-void *array_pop(Array *arr) {
- void *item = array_peek(arr);
- if (!item)
- return NULL;
- arr->len--;
- return item;
-}
-
-void *array_peek(const Array *arr) {
- if (arr->len == 0)
- return NULL;
- return array_get(arr, arr->len - 1);
-}
diff --git a/array.h b/array.h
index 9deac45..67fe7a5 100644
--- a/array.h
+++ b/array.h
@@ -101,26 +101,5 @@ VIS_INTERNAL bool array_resize(Array*, size_t length);
* Sort array, the comparision function works as for `qsort(3)`.
*/
VIS_INTERNAL void array_sort(Array*, int (*compar)(const void*, const void*));
-/**
- * Push item onto the top of the stack.
- * @rst
- * .. note:: Is equivalent to ``array_add(arr, item)``.
- * @endrst
- */
-VIS_INTERNAL bool array_push(Array*, void *item);
-/**
- * Get and remove item at the top of the stack.
- * @rst
- * .. warning:: The same ownership rules as for ``array_get`` apply.
- * @endrst
- */
-VIS_INTERNAL void *array_pop(Array*);
-/**
- * Get item at the top of the stack without removing it.
- * @rst
- * .. warning:: The same ownership rules as for ``array_get`` apply.
- * @endrst
- */
-VIS_INTERNAL void *array_peek(const Array*);
#endif
diff --git a/test/core/array-test.c b/test/core/array-test.c
index 5944904..77d9d36 100644
--- a/test/core/array-test.c
+++ b/test/core/array-test.c
@@ -22,8 +22,6 @@ static void test_small_objects(void) {
ok(arr.len == 0, "Initialization");
ok(!array_set(&arr, 0, NULL) && errno == EINVAL, "Set with invalid index");
ok(array_get(&arr, 0) == NULL && errno == EINVAL, "Get with invalid index");
- ok(array_peek(&arr) == NULL && arr.len == 0, "Peek empty array");
- ok(array_pop(&arr) == NULL && arr.len == 0, "Pop empty array");
for (size_t i = 0; i < len; i++) {
int *v;
@@ -44,11 +42,6 @@ static void test_small_objects(void) {
"Get array element: %zu = %d", i, *v);
}
- int *v;
- ok((v = array_peek(&arr)) && *v == values[0] && arr.len == len, "Peek populated array");
- ok((v = array_pop(&arr)) && *v == values[0] && arr.len == len-1, "Pop populated array");
- ok((v = array_peek(&arr)) && *v == values[1] && arr.len == len-1, "Peek after pop");
-
array_clear(&arr);
ok(arr.len == 0 && array_get(&arr, 0) == NULL && errno == EINVAL, "Clear");
@@ -66,6 +59,7 @@ static void test_small_objects(void) {
ok(!array_remove(&arr, arr.len) && errno == EINVAL, "Remove past end of array");
+ int *v;
size_t len_before = arr.len;
ok(array_remove(&arr, 2) && arr.len == len_before-1 &&
(v = array_get(&arr, 0)) && *v == values[0] &&
diff --git a/vis-core.h b/vis-core.h
index 6c54640..6e601ab 100644
--- a/vis-core.h
+++ b/vis-core.h
@@ -131,12 +131,6 @@ typedef struct {
enum SamError error; /* non-zero in case something went wrong */
} Transcript;
-typedef struct {
- Array prev;
- Array next;
- size_t max;
-} MarkList;
-
struct File { /* shared state among windows displaying the same file */
Text *text; /* data structure holding the file content */
const char *name; /* file name used when loading/saving */
@@ -161,12 +155,15 @@ struct Win {
bool expandtab; /* whether typed tabs should be converted to spaces in this window*/
Vis *vis; /* editor instance to which this window belongs */
File *file; /* file being displayed in this window */
- MarkList jumplist; /* LRU jump management */
Array saved_selections; /* register used to store selections */
Mode modes[VIS_MODE_INVALID]; /* overlay mods used for per window key bindings */
Win *parent; /* window which was active when showing the command prompt */
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];
};
struct Vis {
@@ -283,9 +280,6 @@ VIS_INTERNAL void register_release(Register*);
VIS_INTERNAL void mark_init(Array*);
VIS_INTERNAL void mark_release(Array*);
-VIS_INTERNAL void marklist_init(MarkList*, size_t max);
-VIS_INTERNAL void marklist_release(MarkList*);
-
VIS_INTERNAL const char *register_get(Vis*, Register*, size_t *len);
VIS_INTERNAL const char *register_slot_get(Vis*, Register*, size_t slot, size_t *len);
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';
diff --git a/vis.c b/vis.c
index 5d1591d..d38b367 100644
--- a/vis.c
+++ b/vis.c
@@ -204,7 +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);
- marklist_release(&win->jumplist);
+ for (int i = 0; i < LENGTH(win->mark_set_lru); i++)
+ free(win->mark_set_lru[i].items);
mark_release(&win->saved_selections);
free(win);
}
@@ -383,7 +384,10 @@ Win *window_new_file(Vis *vis, File *file, enum UiOption options) {
window_free(win);
return NULL;
}
- marklist_init(&win->jumplist, 32);
+
+ for (int i = 0; i < LENGTH(win->mark_set_lru); i++)
+ win->mark_set_lru[i].elem_size = sizeof(SelectionRegion);
+
mark_init(&win->saved_selections);
file->refcount++;
win_options_set(win, win->options);
diff --git a/vis.h b/vis.h
index 0b1c331..272df07 100644
--- a/vis.h
+++ b/vis.h
@@ -960,17 +960,17 @@ VIS_EXPORT void vis_mark_normalize(Array *array);
* Add selections of focused window to jump list.
* @param vis The editor instance.
*/
-VIS_EXPORT bool vis_jumplist_save(Vis*);
+VIS_EXPORT void vis_jumplist_save(Vis*);
/**
* Navigate jump list backwards.
* @param vis The editor instance.
*/
-VIS_EXPORT bool vis_jumplist_prev(Vis*);
+VIS_EXPORT void vis_jumplist_prev(Vis*);
/**
* Navigate jump list forwards.
* @param vis The editor instance.
*/
-VIS_EXPORT bool vis_jumplist_next(Vis*);
+VIS_EXPORT void vis_jumplist_next(Vis*);
/** @} */
/*