mirror of
https://github.com/neovim/neovim.git
synced 2026-05-24 05:40:08 +00:00
fix(marks): don't use spell decorations from other lines (#39441)
Spell decorations from other lines aren't relevant to the current line. Also, decor_redraw_col() can only go forward, while spell navigation needs to go both forward and backward.
This commit is contained in:
@@ -1255,15 +1255,10 @@ bool no_spell_checking(win_T *wp)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void decor_spell_nav_start(win_T *wp)
|
||||
{
|
||||
decor_state = (DecorState){ 0 };
|
||||
decor_redraw_reset(wp, &decor_state);
|
||||
}
|
||||
|
||||
static TriState decor_spell_nav_col(win_T *wp, linenr_T lnum, linenr_T *decor_lnum, int col)
|
||||
{
|
||||
if (*decor_lnum != lnum) {
|
||||
decor_redraw_reset(wp, &decor_state);
|
||||
decor_providers_invoke_spell(wp, lnum - 1, col, lnum - 1, -1);
|
||||
decor_redraw_line(wp, lnum - 1, &decor_state);
|
||||
*decor_lnum = lnum;
|
||||
@@ -1331,7 +1326,7 @@ size_t spell_move_to(win_T *wp, int dir, smt_T behaviour, bool curline, hlf_T *a
|
||||
// temporary DecorState.
|
||||
DecorState saved_decor_start = decor_state;
|
||||
linenr_T decor_lnum = -1;
|
||||
decor_spell_nav_start(wp);
|
||||
decor_state = (DecorState){ 0 };
|
||||
|
||||
while (!got_int) {
|
||||
char *line = ml_get_buf(wp->w_buffer, lnum);
|
||||
|
||||
@@ -455,4 +455,125 @@ describe("'spell'", function()
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
local function test_spell_false_nav(ephemeral)
|
||||
screen:try_resize(50, 8)
|
||||
insert('Splel\nSplle\nSepll\nSpele\nSpeel')
|
||||
feed('gg0')
|
||||
exec('set shortmess+=s spell spelloptions=noplainbuffer')
|
||||
|
||||
n.exec_lua(function()
|
||||
local ns = vim.api.nvim_create_namespace('spell')
|
||||
if ephemeral then
|
||||
local decors = {} --- @type [integer,integer,vim.api.keyset.set_extmark][]
|
||||
local function on_do()
|
||||
for _, decor in ipairs(decors) do
|
||||
vim.api.nvim_buf_set_extmark(
|
||||
0,
|
||||
ns,
|
||||
decor[1],
|
||||
decor[2],
|
||||
vim.tbl_deep_extend('error', decor[3], { ephemeral = true })
|
||||
)
|
||||
end
|
||||
end
|
||||
vim.api.nvim_set_decoration_provider(ns, {
|
||||
on_win = on_do,
|
||||
_on_spell_nav = on_do,
|
||||
})
|
||||
function _G.Update(new_decors)
|
||||
decors = new_decors
|
||||
vim.cmd('redraw!')
|
||||
end
|
||||
else
|
||||
--- @param decors [integer,integer,vim.api.keyset.set_extmark][]
|
||||
function _G.Update(decors)
|
||||
vim.api.nvim_buf_clear_namespace(0, ns, 0, -1)
|
||||
for _, decor in ipairs(decors) do
|
||||
vim.api.nvim_buf_set_extmark(0, ns, decor[1], decor[2], decor[3])
|
||||
end
|
||||
vim.cmd('redraw!')
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
n.exec_lua(function()
|
||||
_G.Update({
|
||||
{ 0, 0, { end_row = 5, spell = true, priority = 0 } },
|
||||
{ 2, 0, { end_row = 3, spell = false, priority = 1 } },
|
||||
})
|
||||
end)
|
||||
screen:expect([[
|
||||
{1:^Splel} |
|
||||
{1:Splle} |
|
||||
Sepll |
|
||||
{1:Spele} |
|
||||
{1:Speel} |
|
||||
{0:~ }|*2
|
||||
|
|
||||
]])
|
||||
|
||||
t.eq({ 1, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed(']s')
|
||||
t.eq({ 2, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed(']s')
|
||||
t.eq({ 4, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed(']s')
|
||||
t.eq({ 5, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed(']s')
|
||||
t.eq({ 1, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed('[s')
|
||||
t.eq({ 5, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed('[s')
|
||||
t.eq({ 4, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed('[s')
|
||||
t.eq({ 2, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed('[s')
|
||||
t.eq({ 1, 0 }, api.nvim_win_get_cursor(0))
|
||||
|
||||
n.exec_lua(function()
|
||||
_G.Update({
|
||||
{ 0, 0, { end_row = 5, spell = true, priority = 0 } },
|
||||
{ 3, 0, { end_row = 5, spell = false, priority = 1 } },
|
||||
{ 3, 0, { end_row = 4, spell = true, priority = 2 } },
|
||||
})
|
||||
end)
|
||||
screen:expect([[
|
||||
{1:^Splel} |
|
||||
{1:Splle} |
|
||||
{1:Sepll} |
|
||||
{1:Spele} |
|
||||
Speel |
|
||||
{0:~ }|*2
|
||||
|
|
||||
]])
|
||||
|
||||
t.eq({ 1, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed(']s')
|
||||
t.eq({ 2, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed(']s')
|
||||
t.eq({ 3, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed(']s')
|
||||
t.eq({ 4, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed(']s')
|
||||
t.eq({ 1, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed('[s')
|
||||
t.eq({ 4, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed('[s')
|
||||
t.eq({ 3, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed('[s')
|
||||
t.eq({ 2, 0 }, api.nvim_win_get_cursor(0))
|
||||
feed('[s')
|
||||
t.eq({ 1, 0 }, api.nvim_win_get_cursor(0))
|
||||
end
|
||||
|
||||
describe('spell=false decoration on line with spelling mistake #39441', function()
|
||||
it('using ephemeral decorations', function()
|
||||
test_spell_false_nav(true)
|
||||
end)
|
||||
|
||||
it('using non-ephemeral extmarks', function()
|
||||
test_spell_false_nav(false)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user