feat(extmarks): allow preventing spellchecking with spell = false

This commit is contained in:
Thomas Vigouroux 2022-09-13 09:44:24 +02:00 committed by Lewis Russell
parent 7335a67b57
commit 7e6d785d19
8 changed files with 71 additions and 24 deletions

View File

@ -721,8 +721,12 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
bool ephemeral = false;
OPTION_TO_BOOL(ephemeral, ephemeral, false);
OPTION_TO_BOOL(decor.spell, spell, false);
if (decor.spell) {
if (opts->spell.type == kObjectTypeNil) {
decor.spell = kNone;
} else {
bool spell = false;
OPTION_TO_BOOL(spell, spell, false);
decor.spell = spell ? kTrue : kFalse;
has_decor = true;
}

View File

@ -69,7 +69,11 @@ void bufhl_add_hl_pos_offset(buf_T *buf, int src_id, int hl_id, lpos_T pos_start
void decor_redraw(buf_T *buf, int row1, int row2, Decoration *decor)
{
if (row2 >= row1) {
if (!decor || decor->hl_id || decor_has_sign(decor) || decor->conceal || decor->spell) {
if (!decor
|| decor->hl_id
|| decor_has_sign(decor)
|| decor->conceal
|| decor->spell != kNone) {
redraw_buf_range_later(buf, row1 + 1, row2 + 1);
}
}
@ -309,7 +313,7 @@ next_mark:
bool conceal = 0;
int conceal_char = 0;
int conceal_attr = 0;
bool spell = false;
TriState spell = kNone;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange item = kv_A(state->active, i);
@ -343,8 +347,8 @@ next_mark:
conceal_attr = item.attr_id;
}
}
if (active && item.decor.spell) {
spell = true;
if (active && item.decor.spell != kNone) {
spell = item.decor.spell;
}
if ((item.start_row == state->row && item.start_col <= col)
&& decor_virt_pos(item.decor)

View File

@ -45,7 +45,7 @@ struct Decoration {
bool hl_eol;
bool virt_lines_above;
bool conceal;
bool spell;
TriState spell;
// TODO(bfredl): style, etc
DecorPriority priority;
int col; // fixed col value, like win_col
@ -61,7 +61,7 @@ struct Decoration {
bool ui_watched; // watched for win_extmark
};
#define DECORATION_INIT { KV_INITIAL_VALUE, KV_INITIAL_VALUE, 0, kVTEndOfLine, \
kHlModeUnknown, false, false, false, false, false, \
kHlModeUnknown, false, false, false, false, kNone, \
DECOR_PRIORITY_BASE, 0, 0, NULL, 0, 0, 0, 0, 0, false }
typedef struct {
@ -91,7 +91,7 @@ typedef struct {
int conceal_char;
int conceal_attr;
bool spell;
TriState spell;
} DecorState;
EXTERN DecorState decor_state INIT(= { 0 });

View File

@ -33,6 +33,7 @@
#include "nvim/spell.h"
#include "nvim/state.h"
#include "nvim/syntax.h"
#include "nvim/types.h"
#include "nvim/undo.h"
#include "nvim/window.h"
@ -1722,9 +1723,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
decor_conceal = 2; // really??
}
if (decor_state.spell) {
can_spell = true;
}
can_spell = TRISTATE_TO_BOOL(decor_state.spell, can_spell);
}
// Check spelling (unless at the end of the line).

View File

@ -71,7 +71,7 @@ void extmark_set(buf_T *buf, uint32_t ns_id, uint32_t *idp, int row, colnr_T col
|| decor->conceal
|| decor_has_sign(decor)
|| decor->ui_watched
|| decor->spell) {
|| decor->spell != kNone) {
decor_full = true;
decor = xmemdup(decor, sizeof *decor);
}

View File

@ -1216,7 +1216,14 @@ static bool decor_spell_nav_col(win_T *wp, linenr_T lnum, linenr_T *decor_lnum,
*decor_lnum = lnum;
}
decor_redraw_col(wp->w_buffer, col, col, false, &decor_state);
return decor_state.spell;
return decor_state.spell == kTrue;
}
static inline bool can_syn_spell(win_T *wp, linenr_T lnum, int col)
{
bool can_spell;
(void)syn_get_id(wp, lnum, col, false, &can_spell, false);
return can_spell;
}
/// Moves to the next spell error.
@ -1346,15 +1353,9 @@ 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 = decor_spell_nav_col(wp, lnum, &decor_lnum, col, &decor_error);
if (!can_spell) {
if (has_syntax) {
(void)syn_get_id(wp, lnum, col, false, &can_spell, false);
} else {
can_spell = (wp->w_s->b_p_spo_flags & SPO_NPBUFFER) == 0;
}
}
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));
if (!can_spell) {
attr = HLF_COUNT;

View File

@ -45,6 +45,9 @@ typedef enum {
kTrue = 1,
} TriState;
#define TRISTATE_TO_BOOL(val, \
default) ((val) == kTrue ? true : ((val) == kFalse ? false : (default)))
typedef struct Decoration Decoration;
#endif // NVIM_TYPES_H

View File

@ -176,7 +176,13 @@ describe('decorations providers', function()
beamtrace = {}
local function on_do(kind, ...)
if kind == 'win' or kind == 'spell' then
a.nvim_buf_set_extmark(0, ns, 0, 0, { end_row = 2, end_col = 23, spell = true, ephemeral = true })
a.nvim_buf_set_extmark(0, ns, 0, 0, {
end_row = 2,
end_col = 23,
spell = true,
priority = 20,
ephemeral = true
})
end
table.insert(beamtrace, {kind, ...})
end
@ -234,6 +240,36 @@ describe('decorations providers', function()
{1:~ }|
|
]]}
-- spell=false with lower priority doesn't 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 })
screen:expect{grid=[[
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 })
screen:expect{grid=[[
I am well written text. |
{15:i} am not capitalized. |
I am a {16:^speling} {16:mistakke}. |
|
{1:~ }|
{1:~ }|
{1:~ }|
|
]]}
end)
it('can predefine highlights', function()