diff options
-rw-r--r-- | src/nvim/api/extmark.c | 8 | ||||
-rw-r--r-- | src/nvim/decoration.c | 12 | ||||
-rw-r--r-- | src/nvim/decoration.h | 6 | ||||
-rw-r--r-- | src/nvim/drawline.c | 5 | ||||
-rw-r--r-- | src/nvim/extmark.c | 2 | ||||
-rw-r--r-- | src/nvim/spell.c | 21 | ||||
-rw-r--r-- | src/nvim/types.h | 3 | ||||
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 38 |
8 files changed, 71 insertions, 24 deletions
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index fee6876469..54eb7d9b6b 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -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; } diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index 19e99fa7a6..230d96a15f 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -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) diff --git a/src/nvim/decoration.h b/src/nvim/decoration.h index 9ba621d7a4..8f016c103b 100644 --- a/src/nvim/decoration.h +++ b/src/nvim/decoration.h @@ -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 }); diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index cb7d85a467..6d42b91507 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -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). diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index df87cc8ab6..015799be06 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -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); } diff --git a/src/nvim/spell.c b/src/nvim/spell.c index f24af5c3bf..b1daf4ed23 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -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; diff --git a/src/nvim/types.h b/src/nvim/types.h index fb10bf21d9..d90c623955 100644 --- a/src/nvim/types.h +++ b/src/nvim/types.h @@ -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 diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index 5b62f5b3e1..489c33d8b1 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -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() |