aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2015-08-08 15:00:52 +0300
committerZyX <kp-pav@yandex.ru>2015-10-08 22:00:38 +0300
commit74d5084139423177c88e2c49a74d04afb6c00fb2 (patch)
tree59f9526d82cc4283b6b8c307903218d4ef1397f8 /src
parent0a334f9d33e2b68ce39216207b574d894dd182f4 (diff)
downloadrneovim-74d5084139423177c88e2c49a74d04afb6c00fb2.tar.gz
rneovim-74d5084139423177c88e2c49a74d04afb6c00fb2.tar.bz2
rneovim-74d5084139423177c88e2c49a74d04afb6c00fb2.zip
shada,functests: Add tests for merging ShaDa data
Diffstat (limited to 'src')
-rw-r--r--src/nvim/mark.c6
-rw-r--r--src/nvim/ops.c16
-rw-r--r--src/nvim/shada.c56
3 files changed, 54 insertions, 24 deletions
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 7e1ae42c47..6ab0403e30 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -1175,13 +1175,13 @@ const void *mark_jumplist_iter(const void *const iter, const win_T *const win,
}
const xfmark_T *const iter_mark =
(iter == NULL
- ? &(win->w_jumplist[win->w_jumplistlen - 1])
+ ? &(win->w_jumplist[0])
: (const xfmark_T *const) iter);
*fm = *iter_mark;
- if (iter_mark == &(win->w_jumplist[0])) {
+ if (iter_mark == &(win->w_jumplist[win->w_jumplistlen - 1])) {
return NULL;
} else {
- return iter_mark - 1;
+ return iter_mark + 1;
}
}
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 04c53d30bb..da1eb7afcb 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -5373,7 +5373,7 @@ size_t op_register_amount(void)
/// @param[in] reg Register value.
///
/// @return true on success, false on failure.
-bool register_set(const char name, const yankreg_T reg)
+bool op_register_set(const char name, const yankreg_T reg)
{
int i = op_reg_index(name);
if (i == -1) {
@@ -5382,3 +5382,17 @@ bool register_set(const char name, const yankreg_T reg)
y_regs[i] = reg;
return true;
}
+
+/// Get register with the given name
+///
+/// @param[in] name Register name.
+///
+/// @return Pointer to the register contents or NULL.
+const yankreg_T *op_register_get(const char name)
+{
+ int i = op_reg_index(name);
+ if (i == -1) {
+ return NULL;
+ }
+ return &y_regs[i];
+}
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 6551e319d2..67f299b8f9 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -997,23 +997,13 @@ static const void *shada_hist_iter(const void *const iter,
/// @param[in,out] hms_p Ring buffer and associated structures.
/// @param[in] entry Inserted entry.
/// @param[in] do_iter Determines whether NeoVim own history should
-/// be used.
+/// be used. Must be true only if inserting
+/// entry from current NeoVim history.
/// @param[in] can_free_entry True if entry can be freed.
static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry,
- const bool no_iter, const bool can_free_entry)
+ const bool do_iter, const bool can_free_entry)
{
- HMLList *const hmll = &hms_p->hmll;
- const khiter_t k = kh_get(hmll_entries, &hms_p->hmll.contained_entries,
- entry.data.history_item.string);
- if (k != kh_end(&hmll->contained_entries)) {
- HMLListEntry *const cur_entry = kh_val(&hmll->contained_entries, k);
- if (entry.timestamp > cur_entry->data.timestamp) {
- hmll_remove(hmll, cur_entry);
- } else {
- return;
- }
- }
- if (!no_iter) {
+ if (do_iter) {
if (hms_p->iter == NULL) {
if (hms_p->last_hist_entry.type != kSDItemMissing
&& hms_p->last_hist_entry.timestamp < entry.timestamp) {
@@ -1031,6 +1021,27 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry,
}
}
}
+ HMLList *const hmll = &hms_p->hmll;
+ const khiter_t k = kh_get(hmll_entries, &hms_p->hmll.contained_entries,
+ entry.data.history_item.string);
+ if (k != kh_end(&hmll->contained_entries)) {
+ HMLListEntry *const existing_entry = kh_val(&hmll->contained_entries, k);
+ if (entry.timestamp > existing_entry->data.timestamp) {
+ hmll_remove(hmll, existing_entry);
+ } else if (!do_iter && entry.timestamp == existing_entry->data.timestamp) {
+ // Prefer entry from the current NeoVim instance.
+ if (existing_entry->can_free_entry) {
+ shada_free_shada_entry(&existing_entry->data);
+ }
+ existing_entry->data = entry;
+ existing_entry->can_free_entry = can_free_entry;
+ // Previous key was freed above, as part of freeing the ShaDa entry.
+ kh_key(&hmll->contained_entries, k) = entry.data.history_item.string;
+ return;
+ } else {
+ return;
+ }
+ }
HMLListEntry *insert_after;
HMLL_ITER_BACK(hmll, insert_after) {
if (insert_after->data.timestamp <= entry.timestamp) {
@@ -1315,7 +1326,14 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
shada_free_shada_entry(&cur_entry);
break;
}
- if (!register_set(cur_entry.data.reg.name, (yankreg_T) {
+ if (!force) {
+ const yankreg_T *const reg = op_register_get(cur_entry.data.reg.name);
+ if (reg == NULL || reg->timestamp >= cur_entry.timestamp) {
+ shada_free_shada_entry(&cur_entry);
+ break;
+ }
+ }
+ if (!op_register_set(cur_entry.data.reg.name, (yankreg_T) {
.y_array = (char_u **) cur_entry.data.reg.contents,
.y_size = (linenr_T) cur_entry.data.reg.contents_size,
.y_type = cur_entry.data.reg.type,
@@ -1400,7 +1418,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
if (jl_len < JUMPLISTSIZE) {
curwin->w_jumplistlen++;
}
- if (curwin->w_jumplistidx > i
+ if (curwin->w_jumplistidx >= i
&& curwin->w_jumplistidx + 1 < curwin->w_jumplistlen) {
curwin->w_jumplistidx++;
}
@@ -1491,16 +1509,14 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
sizeof(buf->b_changelist[0]) * (size_t) i);
} else {
memmove(&buf->b_changelist[i + 1], &buf->b_changelist[i],
- sizeof(buf->b_changelist[0])
- * (size_t) (cl_len - i));
+ sizeof(buf->b_changelist[0]) * (size_t) (cl_len - i));
}
} else if (i == 0) {
if (cl_len == JUMPLISTSIZE) {
i = -1;
} else if (cl_len > 0) {
memmove(&buf->b_changelist[1], &buf->b_changelist[0],
- sizeof(buf->b_changelist[0])
- * (size_t) cl_len);
+ sizeof(buf->b_changelist[0]) * (size_t) cl_len);
}
}
if (i != -1) {