Skip to content

Commit 9725df2

Browse files
feat: Support disabling code block backgrounds with highlights
## Details Requested: #110 Currently when we render code blocks we set a background highlight group. This works for most languages, however some set backgrounds as well, an example of this is git `diff`s. Since backgrounds cannot be easily combined we instead allow disabling backgrounds for the languages configured under `code -> disable_background`. Other change is a refactor for context into a class with buffer level manager.
1 parent ef0c921 commit 9725df2

File tree

15 files changed

+319
-215
lines changed

15 files changed

+319
-215
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,9 @@ require('render-markdown').setup({
247247
-- language: adds language icon to sign column if enabled and icon + name above code blocks
248248
-- full: normal + language
249249
style = 'full',
250+
-- An array of language names for which background highlighting will be disabled
251+
-- Likely because that language has background highlights itself
252+
disable_background = { 'diff' },
250253
-- Amount of padding to add to the left of code blocks
251254
left_pad = 0,
252255
-- Amount of padding to add to the right of code blocks when width is 'block'
@@ -507,6 +510,9 @@ require('render-markdown').setup({
507510
-- language: adds language icon to sign column if enabled and icon + name above code blocks
508511
-- full: normal + language
509512
style = 'full',
513+
-- An array of language names for which background highlighting will be disabled
514+
-- Likely because that language has background highlights itself
515+
disable_background = { 'diff' },
510516
-- Amount of padding to add to the left of code blocks
511517
left_pad = 0,
512518
-- Amount of padding to add to the right of code blocks when width is 'block'

doc/render-markdown.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ Full Default Configuration ~
279279
-- language: adds language icon to sign column if enabled and icon + name above code blocks
280280
-- full: normal + language
281281
style = 'full',
282+
-- An array of language names for which background highlighting will be disabled
283+
-- Likely because that language has background highlights itself
284+
disable_background = { 'diff' },
282285
-- Amount of padding to add to the left of code blocks
283286
left_pad = 0,
284287
-- Amount of padding to add to the right of code blocks when width is 'block'
@@ -539,6 +542,9 @@ CODE BLOCKS *render-markdown-setup-code-blocks*
539542
-- language: adds language icon to sign column if enabled and icon + name above code blocks
540543
-- full: normal + language
541544
style = 'full',
545+
-- An array of language names for which background highlighting will be disabled
546+
-- Likely because that language has background highlights itself
547+
disable_background = { 'diff' },
542548
-- Amount of padding to add to the left of code blocks
543549
left_pad = 0,
544550
-- Amount of padding to add to the right of code blocks when width is 'block'

lua/render-markdown/context.lua

Lines changed: 77 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,81 @@
1-
local util = require('render-markdown.util')
2-
3-
---@class render.md.ContextCache
4-
local cache = {
5-
---@type table<integer, table<integer, [integer, integer][]>>
6-
conceal = {},
7-
---@type table<integer, table<integer, [integer, integer, string][]>>
8-
inline_links = {},
9-
}
10-
111
---@class render.md.Context
12-
local M = {}
2+
---@field private buf integer
3+
---@field private win integer
4+
---@field private conceallevel integer
5+
---@field private conceal? table<integer, [integer, integer][]>
6+
---@field private links table<integer, [integer, integer, string][]>
7+
local Context = {}
8+
Context.__index = Context
139

1410
---@param buf integer
15-
function M.reset_buf(buf)
16-
cache.conceal[buf] = {}
17-
cache.inline_links[buf] = {}
11+
---@param win integer
12+
function Context.new(buf, win)
13+
local self = setmetatable({}, Context)
14+
self.buf = buf
15+
self.win = win
16+
self.conceallevel = vim.api.nvim_get_option_value('conceallevel', { scope = 'local', win = win })
17+
self.conceal = nil
18+
self.links = {}
19+
return self
1820
end
1921

20-
---@param buf integer
21-
---@param parser vim.treesitter.LanguageTree
22-
function M.compute_conceal(buf, parser)
22+
---@param info render.md.NodeInfo
23+
---@param icon string
24+
function Context:add_link(info, icon)
25+
local row = info.start_row
26+
if self.links[row] == nil then
27+
self.links[row] = {}
28+
end
29+
table.insert(self.links[row], { info.start_col, info.end_col, icon })
30+
end
31+
32+
---@param row integer
33+
---@return [integer, integer, string][]
34+
function Context:get_links(row)
35+
return self.links[row] or {}
36+
end
37+
38+
---@return integer
39+
function Context:get_width()
40+
return vim.api.nvim_win_get_width(self.win)
41+
end
42+
43+
---@param row integer
44+
---@return [integer, integer][]
45+
function Context:get_conceal(row)
46+
if self.conceal == nil then
47+
self.conceal = self:compute_conceal()
48+
end
49+
return self.conceal[row] or {}
50+
end
51+
52+
---Cached row level implementation of vim.treesitter.get_captures_at_pos
53+
---@private
54+
---@return table<integer, [integer, integer][]>
55+
function Context:compute_conceal()
56+
if self.conceallevel == 0 then
57+
return {}
58+
end
2359
local ranges = {}
24-
if util.get_win(util.buf_to_win(buf), 'conceallevel') > 0 then
25-
parser:for_each_tree(function(tree, language_tree)
26-
local nodes = M.get_conceal_nodes(buf, language_tree:lang(), tree:root())
27-
for _, node in ipairs(nodes) do
28-
local row, start_col, _, end_col = node:range()
29-
if ranges[row] == nil then
30-
ranges[row] = {}
31-
end
32-
table.insert(ranges[row], { start_col, end_col })
60+
local parser = vim.treesitter.get_parser(self.buf)
61+
parser:for_each_tree(function(tree, language_tree)
62+
local nodes = self:compute_conceal_nodes(language_tree:lang(), tree:root())
63+
for _, node in ipairs(nodes) do
64+
local row, start_col, _, end_col = node:range()
65+
if ranges[row] == nil then
66+
ranges[row] = {}
3367
end
34-
end)
35-
end
36-
cache.conceal[buf] = ranges
68+
table.insert(ranges[row], { start_col, end_col })
69+
end
70+
end)
71+
return ranges
3772
end
3873

3974
---@private
40-
---@param buf integer
4175
---@param language string
4276
---@param root TSNode
4377
---@return TSNode[]
44-
function M.get_conceal_nodes(buf, language, root)
78+
function Context:compute_conceal_nodes(language, root)
4579
if not vim.tbl_contains({ 'markdown', 'markdown_inline' }, language) then
4680
return {}
4781
end
@@ -50,38 +84,30 @@ function M.get_conceal_nodes(buf, language, root)
5084
return {}
5185
end
5286
local nodes = {}
53-
for _, node, metadata in query:iter_captures(root, buf) do
87+
for _, node, metadata in query:iter_captures(root, self.buf) do
5488
if metadata.conceal ~= nil then
5589
table.insert(nodes, node)
5690
end
5791
end
5892
return nodes
5993
end
6094

61-
---@param buf integer
62-
---@param row integer
63-
---@return [integer, integer][]
64-
function M.concealed(buf, row)
65-
return cache.conceal[buf][row] or {}
66-
end
95+
---@type table<integer, render.md.Context>
96+
local cache = {}
97+
98+
---@class render.md.ContextManager
99+
local M = {}
67100

68101
---@param buf integer
69-
---@param info render.md.NodeInfo
70-
---@param icon string
71-
function M.add_inline_link(buf, info, icon)
72-
local inline_links = cache.inline_links[buf]
73-
local row = info.start_row
74-
if inline_links[row] == nil then
75-
inline_links[row] = {}
76-
end
77-
table.insert(inline_links[row], { info.start_col, info.end_col, icon })
102+
---@param win integer
103+
function M.reset(buf, win)
104+
cache[buf] = Context.new(buf, win)
78105
end
79106

80107
---@param buf integer
81-
---@param row integer
82-
---@return [integer, integer, string][]
83-
function M.inline_links(buf, row)
84-
return cache.inline_links[buf][row] or {}
108+
---@return render.md.Context
109+
function M.get(buf)
110+
return cache[buf]
85111
end
86112

87113
return M

lua/render-markdown/extmark.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Extmark.__index = Extmark
1111
---@param namespace integer
1212
---@param buf integer
1313
---@param mark render.md.Mark
14+
---@return render.md.Extmark
1415
function Extmark.new(namespace, buf, mark)
1516
local self = setmetatable({}, Extmark)
1617
self.namespace = namespace

0 commit comments

Comments
 (0)