diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua index c0398bbe18..c69d830cda 100644 --- a/runtime/lua/vim/treesitter/highlighter.lua +++ b/runtime/lua/vim/treesitter/highlighter.lua @@ -443,17 +443,22 @@ local function on_range_impl( local url = get_url(match, buf, capture, metadata) if hl and not on_conceal and (not on_spell or spell ~= nil) then - api.nvim_buf_set_extmark(buf, ns, start_row, start_col, { - end_line = end_row, - end_col = end_col, - hl_group = hl, - ephemeral = true, - priority = priority, - conceal = conceal, - spell = spell, - url = url, - _subpriority = subtree_counter, - }) + -- Workaround for #35814: ensure the range is within buffer bounds, + -- allowing the last line if end_col is 0. + -- TODO(skewb1k): investigate a proper concurrency-safe handling of extmarks. + if (end_row + (end_col > 0 and 1 or 0)) <= api.nvim_buf_line_count(buf) then + api.nvim_buf_set_extmark(buf, ns, start_row, start_col, { + end_row = end_row, + end_col = end_col, + hl_group = hl, + ephemeral = true, + priority = priority, + conceal = conceal, + spell = spell, + url = url, + _subpriority = subtree_counter, + }) + end end if diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index 53aa0b1053..a14cf426f4 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -813,8 +813,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer len = opts->ephemeral ? MAXCOL : ml_get_buf_len(buf, (linenr_T)line2 + 1); } else if (line2 == buf->b_ml.ml_line_count) { // We are trying to add an extmark past final newline - // TODO(skewb1k): workaround for #35814. Investigate proper concurrency-safe handling of extmarks. - len = opts->ephemeral ? MAXCOL : 0; + len = 0; } else { // reuse len from before line2 = (int)line;