Skip to content

Commit 8355c85

Browse files
feat: better anti-conceal for multi-line decorations
## Details Previously only the starting row of a mark would be used when deciding whether the mark should be hidden or shown. This means if a mark spanned multiple rows (like with scope highlights) we would only hide the decoration if the users cursor was on the first line, but show it when the cursor was anywhere in the middle. This is okay, but definitely not ideal, so now the logic uses both the start and end row of a mark and hides it if the current row overlaps the mark. We use overlap since in visual mode it is not a single row, but multiple. Now any overlapping marks within the cursor range are hidden. There is a special case for `hl_eol` marks, which specify an end row but do not actually impact that row, instead their impact effectively ends one row earlier. So we handle this case specifically and offset the end of a mark by 1 if `hl_eol` is specified. Hopefully there are no other such edge cases. Minor other changes: - Add unit tests for `range` class - Rename `render.md.Renderer` to `render.md.Render` - Match order of fields in `default_buffer_config()` with class
1 parent 8bb0d47 commit 8355c85

34 files changed

+130
-69
lines changed

benches/medium_table_spec.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ local util = require('benches.util')
44

55
describe('medium-table.md', function()
66
it('default', function()
7-
local base_marks = 337
7+
local base_marks = 341
88
util.less_than(util.setup('temp/medium-table.md'), 120)
99
util.num_marks(base_marks)
1010

benches/util.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---@module 'luassert'
22

3-
local eq = assert.are.same
4-
local truthy = assert.truthy
3+
local Eq = assert.are.same
4+
local True = assert.True
55

66
---@class render.md.bench.Util
77
local M = {}
@@ -52,14 +52,14 @@ end
5252
---@param actual number
5353
---@param max number
5454
function M.less_than(actual, max)
55-
truthy(actual < max, string.format('expected %f < %f', actual, max))
55+
True(actual < max, string.format('expected %f < %f', actual, max))
5656
end
5757

5858
---@param expected integer
5959
function M.num_marks(expected)
6060
local ui = require('render-markdown.core.ui')
6161
local marks = vim.api.nvim_buf_get_extmarks(0, ui.ns, 0, -1, {})
62-
eq(expected, #marks)
62+
Eq(expected, #marks)
6363
end
6464

6565
return M

doc/render-markdown.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*render-markdown.txt* For 0.11.0 Last change: 2025 April 11
1+
*render-markdown.txt* For 0.11.0 Last change: 2025 April 15
22

33
==============================================================================
44
Table of Contents *render-markdown-table-of-contents*

lua/render-markdown/config.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ end
119119
---@return render.md.Range?
120120
function Config:hidden(mode, row)
121121
-- Anti-conceal is not enabled -> hide nothing
122-
-- Row is not known means buffer is not active -> hide nothing
122+
-- Row is not known -> buffer is not active -> hide nothing
123123
if not self.anti_conceal.enabled or row == nil then
124124
return nil
125125
end

lua/render-markdown/core/extmark.lua

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,17 @@ end
2222

2323
---@param range? render.md.Range
2424
---@return boolean
25-
function Extmark:inside(range)
25+
function Extmark:overlaps(range)
2626
if range == nil then
2727
return false
2828
end
29-
local row = self.mark.start_row
30-
return range:contains(row, row)
29+
local top = self.mark.start_row
30+
local bottom = self.mark.opts.end_row or top
31+
-- overlap for hl_eol should not include last line
32+
if self.mark.opts.hl_eol then
33+
bottom = bottom - 1
34+
end
35+
return range:overlaps(top, bottom)
3136
end
3237

3338
---@param ns integer

lua/render-markdown/core/range.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ end
3636
---@param bottom integer
3737
---@return boolean
3838
function Range:overlaps(top, bottom)
39-
return top < self.bottom and bottom >= self.top
39+
return top <= self.bottom and bottom >= self.top
4040
end
4141

4242
---@param ranges render.md.Range[]

lua/render-markdown/core/ui.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ function M.get_row_marks(buf, win)
6464

6565
local marks = {}
6666
for _, extmark in ipairs(buffer:get_marks()) do
67-
if extmark:inside(hidden) then
67+
if extmark:overlaps(hidden) then
6868
marks[#marks + 1] = extmark:get()
6969
end
7070
end
@@ -167,7 +167,7 @@ function M.run_update(buf, win, change)
167167
state.on.initial({ buf = buf, win = win })
168168
end
169169
for _, extmark in ipairs(extmarks) do
170-
if extmark:get().conceal and extmark:inside(hidden) then
170+
if extmark:get().conceal and extmark:overlaps(hidden) then
171171
extmark:hide(M.ns, buf)
172172
else
173173
extmark:show(M.ns, buf)

lua/render-markdown/debug/marks.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ end
5656
---@return string
5757
function Mark:__tostring()
5858
local lines = {}
59-
lines[#lines + 1] = string.rep('=', vim.o.columns - 10)
59+
lines[#lines + 1] = string.rep('=', vim.o.columns - 1)
6060
lines[#lines + 1] = string.format('row: %s', Mark.collapse(self.row))
6161
lines[#lines + 1] = string.format('column: %s', Mark.collapse(self.col))
6262
lines[#lines + 1] = string.format('hide: %s', vim.inspect(self.conceal))

lua/render-markdown/handler/html.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ local ts = require('render-markdown.integ.ts')
88
---@field private context render.md.Context
99
---@field private marks render.md.Marks
1010
---@field private query vim.treesitter.Query
11-
---@field private renderers table<string, render.md.Renderer>
11+
---@field private renderers table<string, render.md.Render>
1212
local Handler = {}
1313
Handler.__index = Handler
1414

lua/render-markdown/handler/markdown.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ local ts = require('render-markdown.integ.ts')
88
---@field private context render.md.Context
99
---@field private marks render.md.Marks
1010
---@field private query vim.treesitter.Query
11-
---@field private renderers table<string, render.md.Renderer>
11+
---@field private renderers table<string, render.md.Render>
1212
local Handler = {}
1313
Handler.__index = Handler
1414

0 commit comments

Comments
 (0)