mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 20:55:18 -07:00
fix(shada): update deleted marks (#24936)
Fix #4295 Close #16067 Co-authored-by: chentau <tchen1998@gmail.com>
This commit is contained in:
parent
67fba9affa
commit
ee56daebb6
@ -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 ']':
|
||||||
|
@ -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
|
||||||
|
@ -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,8 +2207,23 @@ 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)
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user