mirror of
https://github.com/neovim/neovim
synced 2025-07-31 19:02:07 +00:00
shada/context: fully remove jumplist duplicates #10898
- Always load files when cleaning up jumplist. - For Shada: avoids writing duplicate entries, which happens when you read from a shada file with duplicate entries (merging the jumplist while writing sometimes produces duplicate entries, bug?) and then write right away (i.e.: without any `:jumps`, `getjumplist()`, or any jump movement, that is: nothing that calls `cleanup_jumplist` with `loadfiles == true`). - For Context: avoids non-idempotent behavior for the same reason (i.e.: first call to `shada_encode_jumps` does not remove duplicate entries). - Do not set pcmark when dumping jumplist for Context. - Retrieving current Context shouldn't add an entry to the jumplist (which will be removed by a subsequent `cleanup_jumplist` anyway, i.e.: tail entry matching current position), just act like `getjumplist` for instance.
This commit is contained in:
committed by
Justin M. Keyes
parent
b8f2436feb
commit
8b8ecf44f2
@ -1162,14 +1162,12 @@ void mark_col_adjust(
|
|||||||
|
|
||||||
// When deleting lines, this may create duplicate marks in the
|
// When deleting lines, this may create duplicate marks in the
|
||||||
// jumplist. They will be removed here for the specified window.
|
// jumplist. They will be removed here for the specified window.
|
||||||
// When "loadfiles" is true first ensure entries have the "fnum" field set
|
// When "checktail" is true, removes tail jump if it matches current position.
|
||||||
// (this may be a bit slow).
|
void cleanup_jumplist(win_T *wp, bool checktail)
|
||||||
void cleanup_jumplist(win_T *wp, bool loadfiles)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (loadfiles) {
|
// Load all the files from the jump list. This is
|
||||||
// If specified, load all the files from the jump list. This is
|
|
||||||
// needed to properly clean up duplicate entries, but will take some
|
// needed to properly clean up duplicate entries, but will take some
|
||||||
// time.
|
// time.
|
||||||
for (i = 0; i < wp->w_jumplistlen; i++) {
|
for (i = 0; i < wp->w_jumplistlen; i++) {
|
||||||
@ -1178,7 +1176,6 @@ void cleanup_jumplist(win_T *wp, bool loadfiles)
|
|||||||
fname2fnum(&wp->w_jumplist[i]);
|
fname2fnum(&wp->w_jumplist[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int to = 0;
|
int to = 0;
|
||||||
for (int from = 0; from < wp->w_jumplistlen; from++) {
|
for (int from = 0; from < wp->w_jumplistlen; from++) {
|
||||||
@ -1213,8 +1210,8 @@ void cleanup_jumplist(win_T *wp, bool loadfiles)
|
|||||||
|
|
||||||
// When pointer is below last jump, remove the jump if it matches the current
|
// When pointer is below last jump, remove the jump if it matches the current
|
||||||
// line. This avoids useless/phantom jumps. #9805
|
// line. This avoids useless/phantom jumps. #9805
|
||||||
if (loadfiles // otherwise (i.e.: Shada), last entry should be kept
|
if (checktail && wp->w_jumplistlen
|
||||||
&& wp->w_jumplistlen && wp->w_jumplistidx == wp->w_jumplistlen) {
|
&& wp->w_jumplistidx == wp->w_jumplistlen) {
|
||||||
const xfmark_T *fm_last = &wp->w_jumplist[wp->w_jumplistlen - 1];
|
const xfmark_T *fm_last = &wp->w_jumplist[wp->w_jumplistlen - 1];
|
||||||
if (fm_last->fmark.fnum == curbuf->b_fnum
|
if (fm_last->fmark.fnum == curbuf->b_fnum
|
||||||
&& fm_last->fmark.mark.lnum == wp->w_cursor.lnum) {
|
&& fm_last->fmark.mark.lnum == wp->w_cursor.lnum) {
|
||||||
|
@ -2737,6 +2737,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize jump list
|
// Initialize jump list
|
||||||
|
setpcmark();
|
||||||
|
cleanup_jumplist(curwin, false);
|
||||||
wms->jumps_size = shada_init_jumps(wms->jumps, &removable_bufs);
|
wms->jumps_size = shada_init_jumps(wms->jumps, &removable_bufs);
|
||||||
|
|
||||||
// Initialize global marks
|
// Initialize global marks
|
||||||
@ -4086,11 +4088,13 @@ static bool shada_removable(const char *name)
|
|||||||
static inline size_t shada_init_jumps(
|
static inline size_t shada_init_jumps(
|
||||||
PossiblyFreedShadaEntry *jumps, khash_t(bufset) *const removable_bufs)
|
PossiblyFreedShadaEntry *jumps, khash_t(bufset) *const removable_bufs)
|
||||||
{
|
{
|
||||||
// Initialize jump list
|
if (!curwin->w_jumplistlen) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
size_t jumps_size = 0;
|
size_t jumps_size = 0;
|
||||||
const void *jump_iter = NULL;
|
const void *jump_iter = NULL;
|
||||||
setpcmark();
|
|
||||||
cleanup_jumplist(curwin, false);
|
|
||||||
do {
|
do {
|
||||||
xfmark_T fm;
|
xfmark_T fm;
|
||||||
jump_iter = mark_jumplist_iter(jump_iter, curwin, &fm);
|
jump_iter = mark_jumplist_iter(jump_iter, curwin, &fm);
|
||||||
@ -4164,6 +4168,7 @@ void shada_encode_jumps(msgpack_sbuffer *const sbuf)
|
|||||||
khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
|
khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
|
||||||
find_removable_bufs(&removable_bufs);
|
find_removable_bufs(&removable_bufs);
|
||||||
PossiblyFreedShadaEntry jumps[JUMPLISTSIZE];
|
PossiblyFreedShadaEntry jumps[JUMPLISTSIZE];
|
||||||
|
cleanup_jumplist(curwin, true);
|
||||||
size_t jumps_size = shada_init_jumps(jumps, &removable_bufs);
|
size_t jumps_size = shada_init_jumps(jumps, &removable_bufs);
|
||||||
msgpack_packer packer;
|
msgpack_packer packer;
|
||||||
msgpack_packer_init(&packer, sbuf, msgpack_sbuffer_write);
|
msgpack_packer_init(&packer, sbuf, msgpack_sbuffer_write);
|
||||||
|
@ -922,9 +922,7 @@ describe('API', function()
|
|||||||
},
|
},
|
||||||
|
|
||||||
['jumps'] = eval(([[
|
['jumps'] = eval(([[
|
||||||
filter(map(add(
|
filter(map(getjumplist()[0], 'filter(
|
||||||
getjumplist()[0], { 'bufnr': bufnr('%'), 'lnum': getcurpos()[1] }),
|
|
||||||
'filter(
|
|
||||||
{ "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum },
|
{ "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum },
|
||||||
{ k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)')
|
{ k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)')
|
||||||
]]):gsub('\n', '')),
|
]]):gsub('\n', '')),
|
||||||
|
@ -291,9 +291,7 @@ describe('context functions', function()
|
|||||||
|
|
||||||
local with_jumps = {
|
local with_jumps = {
|
||||||
['jumps'] = eval(([[
|
['jumps'] = eval(([[
|
||||||
filter(map(add(
|
filter(map(getjumplist()[0], 'filter(
|
||||||
getjumplist()[0], { 'bufnr': bufnr('%'), 'lnum': getcurpos()[1] }),
|
|
||||||
'filter(
|
|
||||||
{ "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum },
|
{ "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum },
|
||||||
{ k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)')
|
{ k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)')
|
||||||
]]):gsub('\n', ''))
|
]]):gsub('\n', ''))
|
||||||
|
Reference in New Issue
Block a user