aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2015-09-24 00:22:58 +0300
committerZyX <kp-pav@yandex.ru>2015-10-08 22:01:11 +0300
commit2dd8e05f9fa9caef6fc04882dbdd27f387112266 (patch)
treedf4542c2e585db402650ad1511d0960cb3fc5a44
parent0a44d504c86fbbf300fbff8fe82c93050c9436be (diff)
downloadrneovim-2dd8e05f9fa9caef6fc04882dbdd27f387112266.tar.gz
rneovim-2dd8e05f9fa9caef6fc04882dbdd27f387112266.tar.bz2
rneovim-2dd8e05f9fa9caef6fc04882dbdd27f387112266.zip
shada: Fix jump/change list merging code
Errors happens under following conditions: 1. Jump/change list is full. 2. New jump/change list item should go between some of the old ones.
-rw-r--r--src/nvim/shada.c6
-rw-r--r--test/functional/shada/merging_spec.lua42
2 files changed, 45 insertions, 3 deletions
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 9e745431cb..cb5b5087f6 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -1213,10 +1213,10 @@ static inline bool marks_equal(const pos_T a, const pos_T b)
if (i > 0) { \
if (jl_len == JUMPLISTSIZE) { \
free_func(jumps[0]); \
- if (i == JUMPLISTSIZE) { \
- i = JUMPLISTSIZE - 1; \
+ i--; \
+ if (i > 0) { \
+ memmove(&jumps[0], &jumps[1], sizeof(jumps[1]) * (size_t) i); \
} \
- memmove(&jumps[0], &jumps[1], sizeof(jumps[1]) * (size_t) i); \
} else if (i != jl_len) { \
memmove(&jumps[i + 1], &jumps[i], \
sizeof(jumps[0]) * (size_t) (jl_len - i)); \
diff --git a/test/functional/shada/merging_spec.lua b/test/functional/shada/merging_spec.lua
index f7a3c4d9ca..b880bdae8a 100644
--- a/test/functional/shada/merging_spec.lua
+++ b/test/functional/shada/merging_spec.lua
@@ -990,4 +990,46 @@ describe('ShaDa changes support code', function()
end
eq(found, 100)
end)
+
+ it('merges JUMPLISTSIZE changes when writing, with new items between old',
+ function()
+ nvim_command('edit /a/b/c')
+ nvim_command('keepjumps call setline(1, range(202))')
+ local shada = ''
+ for i = 1,101 do
+ local t = i * 2
+ shada = shada .. (
+ '\011\204%c\019\131\162mX\195\161f\196\006/a/b/c\161l\204%c'
+ ):format(t, t)
+ end
+ wshada(shada)
+ eq(0, exc_exec(sdrcmd()))
+ local shada = ''
+ for i = 1,100 do
+ shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c'
+ ):format(i, i)
+ end
+ local changes = {}
+ for i = 1, 100 do
+ changes[i] = {line=i}
+ end
+ for i = 1, 101 do
+ local t = i * 2
+ changes[(t > #changes + 1) and (#changes + 1) or t] = {line=t}
+ end
+ wshada(shada)
+ eq(0, exc_exec('wshada ' .. shada_fname))
+ local shift = #changes - 100
+ for i = 1,100 do
+ changes[i] = changes[i + shift]
+ end
+ local found = 0
+ for _, v in ipairs(read_shada_file(shada_fname)) do
+ if v.type == 11 and v.value.f == '/a/b/c' then
+ found = found + 1
+ eq(changes[found].line, v.value.l)
+ end
+ end
+ eq(found, 100)
+ end)
end)