neovim-32619.patch 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua
  2. index db4475e7e4..766f5f5416 100644
  3. --- a/runtime/lua/vim/treesitter/highlighter.lua
  4. +++ b/runtime/lua/vim/treesitter/highlighter.lua
  5. @@ -52,11 +52,14 @@ function TSHighlighterQuery:query()
  6. return self._query
  7. end
  8. +---@alias MarkInfo { start_line: integer, start_col: integer, opts: vim.api.keyset.set_extmark }
  9. +
  10. ---@class (private) vim.treesitter.highlighter.State
  11. ---@field tstree TSTree
  12. ---@field next_row integer
  13. ---@field iter vim.treesitter.highlighter.Iter?
  14. ---@field highlighter_query vim.treesitter.highlighter.Query
  15. +---@field prev_marks MarkInfo[]
  16. ---@nodoc
  17. ---@class vim.treesitter.highlighter
  18. @@ -220,6 +223,7 @@ function TSHighlighter:prepare_highlight_states(win, srow, erow)
  19. next_row = 0,
  20. iter = nil,
  21. highlighter_query = hl_query,
  22. + prev_marks = {},
  23. })
  24. end)
  25. end
  26. @@ -311,6 +315,35 @@ local function get_spell(capture_name)
  27. return nil, 0
  28. end
  29. +---Adds the mark to the buffer, clipped by the line.
  30. +---Queues the remainder if the mark continues after the line.
  31. +---@param m MarkInfo
  32. +---@param buf integer
  33. +---@param line integer
  34. +---@param next_marks MarkInfo[]
  35. +local function add_mark(m, buf, line, next_marks)
  36. + local cur_start_l = m.start_line
  37. + local cur_start_c = m.start_col
  38. + if cur_start_l < line then
  39. + cur_start_l = line
  40. + cur_start_c = 0
  41. + end
  42. +
  43. + local cur_opts = m.opts
  44. + if cur_opts.end_line >= line + 1 then
  45. + cur_opts = vim.deepcopy(cur_opts, true)
  46. + cur_opts.end_line = line + 1
  47. + cur_opts.end_col = 0
  48. + table.insert(next_marks, m)
  49. + end
  50. +
  51. + local empty = cur_opts.end_line < cur_start_l
  52. + or (cur_opts.end_line == cur_start_l and cur_opts.end_col <= cur_start_c)
  53. + if cur_start_l <= line and not empty then
  54. + api.nvim_buf_set_extmark(buf, ns, cur_start_l, cur_start_c, cur_opts)
  55. + end
  56. +end
  57. +
  58. ---@param self vim.treesitter.highlighter
  59. ---@param win integer
  60. ---@param buf integer
  61. @@ -328,6 +361,12 @@ local function on_line_impl(self, win, buf, line, on_spell, on_conceal)
  62. return
  63. end
  64. + local next_marks = {}
  65. +
  66. + for _, mark in ipairs(state.prev_marks) do
  67. + add_mark(mark, buf, line, next_marks)
  68. + end
  69. +
  70. if state.iter == nil or state.next_row < line then
  71. -- Mainly used to skip over folds
  72. @@ -367,7 +406,7 @@ local function on_line_impl(self, win, buf, line, on_spell, on_conceal)
  73. local url = get_url(match, buf, capture, metadata)
  74. if hl and end_row >= line and not on_conceal and (not on_spell or spell ~= nil) then
  75. - api.nvim_buf_set_extmark(buf, ns, start_row, start_col, {
  76. + local opts = {
  77. end_line = end_row,
  78. end_col = end_col,
  79. hl_group = hl,
  80. @@ -376,7 +415,9 @@ local function on_line_impl(self, win, buf, line, on_spell, on_conceal)
  81. conceal = conceal,
  82. spell = spell,
  83. url = url,
  84. - })
  85. + }
  86. + local mark = { start_line = start_row, start_col = start_col, opts = opts }
  87. + add_mark(mark, buf, line, next_marks)
  88. end
  89. if
  90. @@ -395,6 +436,8 @@ local function on_line_impl(self, win, buf, line, on_spell, on_conceal)
  91. state.next_row = start_row
  92. end
  93. end
  94. +
  95. + state.prev_marks = next_marks
  96. end)
  97. end