fix(shada): update deleted marks (#24936)

Fix #4295
Close #16067

Co-authored-by: chentau <tchen1998@gmail.com>
This commit is contained in:
Maria José Solano 2023-08-30 19:15:49 -07:00 committed by GitHub
parent 67fba9affa
commit ee56daebb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 7 deletions

View File

@ -51,9 +51,6 @@
// There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing // There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing
// shada). // shada).
/// Global marks (marks with file number or name)
static xfmark_T namedfm[NGLOBALMARKS];
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "mark.c.generated.h" # include "mark.c.generated.h"
#endif #endif
@ -935,6 +932,7 @@ void ex_delmarks(exarg_T *eap)
emsg(_(e_argreq)); emsg(_(e_argreq));
} else { } else {
// clear specified marks only // clear specified marks only
const Timestamp timestamp = os_time();
for (p = eap->arg; *p != NUL; p++) { for (p = eap->arg; *p != NUL; p++) {
lower = ASCII_ISLOWER(*p); lower = ASCII_ISLOWER(*p);
digit = ascii_isdigit(*p); digit = ascii_isdigit(*p);
@ -959,6 +957,7 @@ void ex_delmarks(exarg_T *eap)
for (int i = from; i <= to; i++) { for (int i = from; i <= to; i++) {
if (lower) { if (lower) {
curbuf->b_namedm[i - 'a'].mark.lnum = 0; curbuf->b_namedm[i - 'a'].mark.lnum = 0;
curbuf->b_namedm[i - 'a'].timestamp = timestamp;
} else { } else {
if (digit) { if (digit) {
n = i - '0' + NMARKS; n = i - '0' + NMARKS;
@ -967,17 +966,24 @@ void ex_delmarks(exarg_T *eap)
} }
namedfm[n].fmark.mark.lnum = 0; namedfm[n].fmark.mark.lnum = 0;
namedfm[n].fmark.fnum = 0; namedfm[n].fmark.fnum = 0;
namedfm[n].fmark.timestamp = timestamp;
XFREE_CLEAR(namedfm[n].fname); XFREE_CLEAR(namedfm[n].fname);
} }
} }
} else { } else {
switch (*p) { switch (*p) {
case '"': case '"':
CLEAR_FMARK(&curbuf->b_last_cursor); break; curbuf->b_last_cursor.timestamp = timestamp;
CLEAR_FMARK(&curbuf->b_last_cursor);
break;
case '^': case '^':
CLEAR_FMARK(&curbuf->b_last_insert); break; curbuf->b_last_insert.timestamp = timestamp;
CLEAR_FMARK(&curbuf->b_last_insert);
break;
case '.': case '.':
CLEAR_FMARK(&curbuf->b_last_change); break; curbuf->b_last_change.timestamp = timestamp;
CLEAR_FMARK(&curbuf->b_last_change);
break;
case '[': case '[':
curbuf->b_op_start.lnum = 0; break; curbuf->b_op_start.lnum = 0; break;
case ']': case ']':

View File

@ -86,4 +86,7 @@ typedef struct xfilemark {
#define INIT_XFMARK { INIT_FMARK, NULL } #define INIT_XFMARK { INIT_FMARK, NULL }
/// Global marks (marks with file number or name)
EXTERN xfmark_T namedfm[NGLOBALMARKS] INIT(= { 0 });
#endif // NVIM_MARK_DEFS_H #endif // NVIM_MARK_DEFS_H

View File

@ -2160,6 +2160,12 @@ static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_re
shada_free_shada_entry(&entry); shada_free_shada_entry(&entry);
break; break;
} }
if (wms->global_marks[idx].data.type == kSDItemMissing) {
if (namedfm[idx].fmark.timestamp >= entry.timestamp) {
shada_free_shada_entry(&entry);
break;
}
}
COMPARE_WITH_ENTRY(&wms->global_marks[idx], entry); COMPARE_WITH_ENTRY(&wms->global_marks[idx], entry);
} }
break; break;
@ -2189,6 +2195,7 @@ static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_re
entry; entry;
} else { } else {
PossiblyFreedShadaEntry *const wms_entry = &filemarks->marks[idx]; PossiblyFreedShadaEntry *const wms_entry = &filemarks->marks[idx];
bool set_wms = true;
if (wms_entry->data.type != kSDItemMissing) { if (wms_entry->data.type != kSDItemMissing) {
if (wms_entry->data.timestamp >= entry.timestamp) { if (wms_entry->data.timestamp >= entry.timestamp) {
shada_free_shada_entry(&entry); shada_free_shada_entry(&entry);
@ -2200,9 +2207,24 @@ static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_re
} }
shada_free_shada_entry(&wms_entry->data); shada_free_shada_entry(&wms_entry->data);
} }
} else {
FOR_ALL_BUFFERS(buf) {
if (buf->b_ffname != NULL
&& path_fnamecmp(entry.data.filemark.fname, buf->b_ffname) == 0) {
fmark_T fm;
mark_get(buf, curwin, &fm, kMarkBufLocal, (int)entry.data.filemark.name);
if (fm.timestamp >= entry.timestamp) {
set_wms = false;
shada_free_shada_entry(&entry);
break;
} }
}
}
}
if (set_wms) {
*wms_entry = pfs_entry; *wms_entry = pfs_entry;
} }
}
} else { } else {
#define AFTERFREE_DUMMY(entry) #define AFTERFREE_DUMMY(entry)
#define DUMMY_IDX_ADJ(i) #define DUMMY_IDX_ADJ(i)

View File

@ -3,6 +3,7 @@ local helpers = require('test.functional.helpers')(after_each)
local meths, curwinmeths, curbufmeths, nvim_command, funcs, eq = local meths, curwinmeths, curbufmeths, nvim_command, funcs, eq =
helpers.meths, helpers.curwinmeths, helpers.curbufmeths, helpers.command, helpers.meths, helpers.curwinmeths, helpers.curbufmeths, helpers.command,
helpers.funcs, helpers.eq helpers.funcs, helpers.eq
local feed = helpers.feed
local exc_exec, exec_capture = helpers.exc_exec, helpers.exec_capture local exc_exec, exec_capture = helpers.exc_exec, helpers.exec_capture
local expect_exit = helpers.expect_exit local expect_exit = helpers.expect_exit
@ -248,4 +249,24 @@ describe('ShaDa support code', function()
eq('', funcs.system(argv)) eq('', funcs.system(argv))
eq(0, exc_exec('rshada')) eq(0, exc_exec('rshada'))
end) end)
it('updates deleted marks', function()
nvim_command('edit ' .. testfilename)
nvim_command('mark A')
nvim_command('mark a')
-- create a change to set the '.' mark,
-- since it can't be set via :mark
feed('ggifoobar<esc>')
nvim_command('wshada')
nvim_command('normal! `A`a`.')
nvim_command('delmarks A a .')
nvim_command('wshada')
reset()
eq('Vim(normal):E20: Mark not set', exc_exec('normal! `A'))
eq('Vim(normal):E20: Mark not set', exc_exec('normal! `a'))
eq('Vim(normal):E20: Mark not set', exc_exec('normal! `.'))
end)
end) end)