aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-05-01 12:30:55 +0800
committerGitHub <noreply@github.com>2023-05-01 12:30:55 +0800
commita803bff89c89cc63e549a3c791fa07d91d1106c8 (patch)
tree23503fa40adaf199dea7e6c9302385ac8e1e42be
parent9f9cef1b569e226a87c5c74e455bc4fc76cc2fac (diff)
downloadrneovim-a803bff89c89cc63e549a3c791fa07d91d1106c8.tar.gz
rneovim-a803bff89c89cc63e549a3c791fa07d91d1106c8.tar.bz2
rneovim-a803bff89c89cc63e549a3c791fa07d91d1106c8.zip
fix(spell): extmark with spell=false should disable spell (#23400)
-rw-r--r--src/nvim/spell.c21
-rw-r--r--test/functional/ui/decorations_spec.lua117
-rw-r--r--test/functional/ui/spell_spec.lua139
3 files changed, 202 insertions, 75 deletions
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 0784c4c8ff..d1d1b9180f 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -1206,8 +1206,8 @@ static void decor_spell_nav_start(win_T *wp)
decor_redraw_reset(wp, &decor_state);
}
-static bool decor_spell_nav_col(win_T *wp, linenr_T lnum, linenr_T *decor_lnum, int col,
- char **decor_error)
+static TriState decor_spell_nav_col(win_T *wp, linenr_T lnum, linenr_T *decor_lnum, int col,
+ char **decor_error)
{
if (*decor_lnum != lnum) {
decor_providers_invoke_spell(wp, lnum - 1, col, lnum - 1, -1, decor_error);
@@ -1215,7 +1215,7 @@ static bool decor_spell_nav_col(win_T *wp, linenr_T lnum, linenr_T *decor_lnum,
*decor_lnum = lnum;
}
decor_redraw_col(wp, col, col, false, &decor_state);
- return decor_state.spell == kTrue;
+ return decor_state.spell;
}
static inline bool can_syn_spell(win_T *wp, linenr_T lnum, int col)
@@ -1352,9 +1352,18 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att
: p - buf) > wp->w_cursor.col)) {
col = (colnr_T)(p - buf);
- bool can_spell = (!has_syntax && (wp->w_s->b_p_spo_flags & SPO_NPBUFFER) == 0)
- || decor_spell_nav_col(wp, lnum, &decor_lnum, col, &decor_error)
- || (has_syntax && can_syn_spell(wp, lnum, col));
+ bool no_plain_buffer = (wp->w_s->b_p_spo_flags & SPO_NPBUFFER) != 0;
+ bool can_spell = !no_plain_buffer;
+ switch (decor_spell_nav_col(wp, lnum, &decor_lnum, col, &decor_error)) {
+ case kTrue:
+ can_spell = true; break;
+ case kFalse:
+ can_spell = false; break;
+ case kNone:
+ if (has_syntax) {
+ can_spell = can_syn_spell(wp, lnum, col);
+ }
+ }
if (!can_spell) {
attr = HLF_COUNT;
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua
index 5792c9703d..f531878bc6 100644
--- a/test/functional/ui/decorations_spec.lua
+++ b/test/functional/ui/decorations_spec.lua
@@ -8,6 +8,7 @@ local exec_lua = helpers.exec_lua
local exec = helpers.exec
local expect_events = helpers.expect_events
local meths = helpers.meths
+local curbufmeths = helpers.curbufmeths
local command = helpers.command
describe('decorations providers', function()
@@ -31,8 +32,9 @@ describe('decorations providers', function()
[12] = {foreground = tonumber('0x990000')};
[13] = {background = Screen.colors.LightBlue};
[14] = {background = Screen.colors.WebGray, foreground = Screen.colors.DarkBlue};
- [15] = {special = Screen.colors.Blue1, undercurl = true},
+ [15] = {special = Screen.colors.Blue, undercurl = true},
[16] = {special = Screen.colors.Red, undercurl = true},
+ [17] = {foreground = Screen.colors.Red},
}
end)
@@ -201,14 +203,14 @@ describe('decorations providers', function()
feed "gg0"
screen:expect{grid=[[
- ^I am well written text. |
- {15:i} am not capitalized. |
- I am a {16:speling} {16:mistakke}. |
- |
- {1:~ }|
- {1:~ }|
- {1:~ }|
- |
+ ^I am well written text. |
+ {15:i} am not capitalized. |
+ I am a {16:speling} {16:mistakke}. |
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
]]}
feed "]s"
@@ -216,14 +218,14 @@ describe('decorations providers', function()
{ "spell", 1000, 1, 1, 0, 1, -1 };
}
screen:expect{grid=[[
- I am well written text. |
- {15:^i} am not capitalized. |
- I am a {16:speling} {16:mistakke}. |
- |
- {1:~ }|
- {1:~ }|
- {1:~ }|
- |
+ I am well written text. |
+ {15:^i} am not capitalized. |
+ I am a {16:speling} {16:mistakke}. |
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
]]}
feed "]s"
@@ -231,43 +233,68 @@ describe('decorations providers', function()
{ "spell", 1000, 1, 2, 7, 2, -1 };
}
screen:expect{grid=[[
- I am well written text. |
- {15:i} am not capitalized. |
- I am a {16:^speling} {16:mistakke}. |
- |
- {1:~ }|
- {1:~ }|
- {1:~ }|
- |
+ I am well written text. |
+ {15:i} am not capitalized. |
+ I am a {16:^speling} {16:mistakke}. |
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
]]}
- -- spell=false with lower priority doesn't disable spell
+ -- spell=false with higher priority does disable spell
local ns = meths.create_namespace "spell"
- local id = helpers.curbufmeths.set_extmark(ns, 0, 0, { priority = 30, end_row = 2, end_col = 23, spell = false })
+ local id = curbufmeths.set_extmark(ns, 0, 0, { priority = 30, end_row = 2, end_col = 23, spell = false })
screen:expect{grid=[[
- I am well written text. |
- i am not capitalized. |
- I am a ^speling mistakke. |
- |
- {1:~ }|
- {1:~ }|
- {1:~ }|
- |
+ I am well written text. |
+ i am not capitalized. |
+ I am a ^speling mistakke. |
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
]]}
- -- spell=false with higher priority does disable spell
- helpers.curbufmeths.set_extmark(ns, 0, 0, { id = id, priority = 10, end_row = 2, end_col = 23, spell = false })
+ feed "]s"
+ screen:expect{grid=[[
+ I am well written text. |
+ i am not capitalized. |
+ I am a ^speling mistakke. |
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {17:search hit BOTTOM, continuing at TOP} |
+ ]]}
+ command('echo ""')
+
+ -- spell=false with lower priority doesn't disable spell
+ curbufmeths.set_extmark(ns, 0, 0, { id = id, priority = 10, end_row = 2, end_col = 23, spell = false })
+
+ screen:expect{grid=[[
+ I am well written text. |
+ {15:i} am not capitalized. |
+ I am a {16:^speling} {16:mistakke}. |
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+ feed "]s"
screen:expect{grid=[[
- I am well written text. |
- {15:i} am not capitalized. |
- I am a {16:^speling} {16:mistakke}. |
- |
- {1:~ }|
- {1:~ }|
- {1:~ }|
- |
+ I am well written text. |
+ {15:i} am not capitalized. |
+ I am a {16:speling} {16:^mistakke}. |
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
]]}
end)
diff --git a/test/functional/ui/spell_spec.lua b/test/functional/ui/spell_spec.lua
index 361f83d1ce..15819aef40 100644
--- a/test/functional/ui/spell_spec.lua
+++ b/test/functional/ui/spell_spec.lua
@@ -6,6 +6,8 @@ local clear = helpers.clear
local feed = helpers.feed
local insert = helpers.insert
local command = helpers.command
+local meths = helpers.meths
+local curbufmeths = helpers.curbufmeths
local is_os = helpers.is_os
describe("'spell'", function()
@@ -18,11 +20,13 @@ describe("'spell'", function()
screen:set_default_attr_ids( {
[0] = {bold=true, foreground=Screen.colors.Blue},
[1] = {special = Screen.colors.Red, undercurl = true},
- [2] = {special = Screen.colors.Blue1, undercurl = true},
+ [2] = {special = Screen.colors.Blue, undercurl = true},
[3] = {foreground = tonumber('0x6a0dad')},
[4] = {foreground = Screen.colors.Magenta},
[5] = {bold = true, foreground = Screen.colors.SeaGreen},
[6] = {foreground = Screen.colors.Red},
+ [7] = {foreground = Screen.colors.Blue},
+ [8] = {foreground = Screen.colors.Blue, special = Screen.colors.Red, undercurl = true},
})
end)
@@ -74,93 +78,180 @@ describe("'spell'", function()
]])
end)
- it('"noplainbuffer" and syntax #20385', function()
+ it('extmarks, "noplainbuffer" and syntax #20385 #23398', function()
command('set filetype=c')
command('syntax on')
command('set spell')
insert([[
#include <stdbool.h>
- bool func(void);]])
+ bool func(void);
+ // I am a speling mistakke]])
+ feed('ge')
screen:expect([[
{3:#include }{4:<stdbool.h>} |
- {5:bool} func({5:void})^; |
+ {5:bool} func({5:void}); |
+ {7:// I am a }{8:spelin^g}{7: }{8:mistakke} |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
+ |
+ ]])
+ feed(']s')
+ screen:expect([[
+ {3:#include }{4:<stdbool.h>} |
+ {5:bool} func({5:void}); |
+ {7:// I am a }{8:speling}{7: }{8:^mistakke} |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ feed(']s')
+ screen:expect([[
+ {3:#include }{4:<stdbool.h>} |
+ {5:bool} func({5:void}); |
+ {7:// I am a }{8:^speling}{7: }{8:mistakke} |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {6:search hit BOTTOM, continuing at TOP} |
+ ]])
+ command('echo ""')
+ local ns = meths.create_namespace("spell")
+ -- extmark with spell=true enables spell
+ local id = curbufmeths.set_extmark(ns, 1, 4, { end_row = 1, end_col = 10, spell = true })
+ screen:expect([[
+ {3:#include }{4:<stdbool.h>} |
+ {5:bool} {1:func}({5:void}); |
+ {7:// I am a }{8:^speling}{7: }{8:mistakke} |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
{0:~ }|
|
]])
feed('[s')
screen:expect([[
{3:#include }{4:<stdbool.h>} |
- {5:bool} func({5:void})^; |
+ {5:bool} {1:^func}({5:void}); |
+ {7:// I am a }{8:speling}{7: }{8:mistakke} |
+ {0:~ }|
+ {0:~ }|
{0:~ }|
{0:~ }|
+ |
+ ]])
+ curbufmeths.del_extmark(ns, id)
+ -- extmark with spell=false disables spell
+ id = curbufmeths.set_extmark(ns, 2, 18, { end_row = 2, end_col = 26, spell = false })
+ screen:expect([[
+ {3:#include }{4:<stdbool.h>} |
+ {5:bool} ^func({5:void}); |
+ {7:// I am a }{8:speling}{7: mistakke} |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ feed('[s')
+ screen:expect([[
+ {3:#include }{4:<stdbool.h>} |
+ {5:bool} func({5:void}); |
+ {7:// I am a }{8:^speling}{7: mistakke} |
+ {0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{6:search hit TOP, continuing at BOTTOM} |
]])
+ command('echo ""')
+ curbufmeths.del_extmark(ns, id)
+ screen:expect([[
+ {3:#include }{4:<stdbool.h>} |
+ {5:bool} func({5:void}); |
+ {7:// I am a }{8:^speling}{7: }{8:mistakke} |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+ feed(']s')
+ screen:expect([[
+ {3:#include }{4:<stdbool.h>} |
+ {5:bool} func({5:void}); |
+ {7:// I am a }{8:speling}{7: }{8:^mistakke} |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
-- "noplainbuffer" shouldn't change spellchecking behavior with syntax enabled
command('set spelloptions+=noplainbuffer')
screen:expect_unchanged()
- feed(']s')
+ feed('[s')
screen:expect([[
{3:#include }{4:<stdbool.h>} |
- {5:bool} func({5:void})^; |
- {0:~ }|
+ {5:bool} func({5:void}); |
+ {7:// I am a }{8:^speling}{7: }{8:mistakke} |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
- {6:search hit BOTTOM, continuing at TOP} |
+ |
]])
-- no spellchecking with "noplainbuffer" and syntax disabled
command('syntax off')
screen:expect([[
#include <stdbool.h> |
- bool func(void)^; |
+ bool func(void); |
+ // I am a ^speling mistakke |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
- {0:~ }|
- {6:search hit BOTTOM, continuing at TOP} |
+ |
]])
- feed('[s')
+ feed(']s')
screen:expect([[
#include <stdbool.h> |
- bool func(void)^; |
+ bool func(void); |
+ // I am a ^speling mistakke |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
- {0:~ }|
- {6:search hit TOP, continuing at BOTTOM} |
+ {6:search hit BOTTOM, continuing at TOP} |
]])
+ command('echo ""')
-- everything is spellchecked without "noplainbuffer" with syntax disabled
command('set spelloptions&')
screen:expect([[
#include <{1:stdbool}.h> |
- {1:bool} {1:func}(void)^; |
- {0:~ }|
+ {1:bool} {1:func}(void); |
+ // I am a {1:^speling} {1:mistakke} |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
- {6:search hit TOP, continuing at BOTTOM} |
+ |
]])
- feed(']s')
+ feed('[s')
screen:expect([[
- #include <{1:^stdbool}.h> |
- {1:bool} {1:func}(void); |
- {0:~ }|
+ #include <{1:stdbool}.h> |
+ {1:bool} {1:^func}(void); |
+ // I am a {1:speling} {1:mistakke} |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
- {6:search hit BOTTOM, continuing at TOP} |
+ |
]])
end)
+
end)