Skip to content

Commit efb4c48

Browse files
fix: indented table border
## Details Issue: #191 When calulating the leading spaces for a table row to determine how much to indent a border only the node text was used. However if tables are indented enough under a list item a leading continuation node eats some of the spaces. This does not happen consistently between the heading and other rows resulting in the number of spaces appearing different. When this occurs we assume the table is not properly aligned on the left and do not render a border. To fix this caclulate the number of leadings spaces using the entire line for the row and not just the node text. Other unrelated changes: - Move treesitter queries out of treesitter module and into where they are actually used - Use the treesitter module to cache parsed queries to avoid parsing more than once per unique query - This also avoid needing to do a vim.schedule in our state setup, instead the queries end up being naturally lazily evaluated
1 parent b0fe71f commit efb4c48

File tree

7 files changed

+98
-80
lines changed

7 files changed

+98
-80
lines changed

lua/render-markdown/core/treesitter.lua

Lines changed: 14 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,20 @@
1+
---@type table<string, vim.treesitter.Query>
2+
local queries = {}
3+
14
---@class render.md.TreeSitter
25
local M = {}
36

4-
---@class render.md.treesitter.Queries
5-
M.queries = {
6-
markdown = [[
7-
(section) @section
8-
9-
(atx_heading [
10-
(atx_h1_marker)
11-
(atx_h2_marker)
12-
(atx_h3_marker)
13-
(atx_h4_marker)
14-
(atx_h5_marker)
15-
(atx_h6_marker)
16-
] @heading)
17-
(setext_heading) @heading
18-
19-
[
20-
(thematic_break)
21-
(minus_metadata)
22-
(plus_metadata)
23-
] @dash
24-
25-
(fenced_code_block) @code
26-
27-
[
28-
(list_marker_plus)
29-
(list_marker_minus)
30-
(list_marker_star)
31-
] @list_marker
32-
33-
[
34-
(task_list_marker_unchecked)
35-
(task_list_marker_checked)
36-
] @checkbox
37-
38-
(block_quote) @quote
39-
40-
(pipe_table) @table
41-
]],
42-
markdown_quote = [[
43-
[
44-
(block_quote_marker)
45-
(block_continuation)
46-
] @quote_marker
47-
]],
48-
inline = [[
49-
(code_span) @code
50-
51-
(shortcut_link) @shortcut
52-
53-
[
54-
(image)
55-
(email_autolink)
56-
(inline_link)
57-
(full_reference_link)
58-
] @link
59-
]],
60-
}
7+
---@param language string
8+
---@param query string
9+
---@return vim.treesitter.Query
10+
function M.parse(language, query)
11+
local result = queries[query]
12+
if result == nil then
13+
result = vim.treesitter.query.parse(language, query)
14+
queries[query] = result
15+
end
16+
return result
17+
end
6118

6219
---@param language string
6320
---@param injection render.md.Injection?

lua/render-markdown/handler/markdown.lua

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ local Context = require('render-markdown.core.context')
22
local list = require('render-markdown.core.list')
33
local log = require('render-markdown.core.log')
44
local state = require('render-markdown.state')
5+
local treesitter = require('render-markdown.core.treesitter')
56

67
---@class render.md.handler.buf.Markdown
78
---@field private marks render.md.Marks
89
---@field private config render.md.buffer.Config
910
---@field private context render.md.Context
11+
---@field private query vim.treesitter.Query
1012
---@field private renderers table<string, render.md.Renderer>
1113
local Handler = {}
1214
Handler.__index = Handler
@@ -18,6 +20,45 @@ function Handler.new(buf)
1820
self.marks = list.new_marks()
1921
self.config = state.get(buf)
2022
self.context = Context.get(buf)
23+
self.query = treesitter.parse(
24+
'markdown',
25+
[[
26+
(section) @section
27+
28+
(atx_heading [
29+
(atx_h1_marker)
30+
(atx_h2_marker)
31+
(atx_h3_marker)
32+
(atx_h4_marker)
33+
(atx_h5_marker)
34+
(atx_h6_marker)
35+
] @heading)
36+
(setext_heading) @heading
37+
38+
[
39+
(thematic_break)
40+
(minus_metadata)
41+
(plus_metadata)
42+
] @dash
43+
44+
(fenced_code_block) @code
45+
46+
[
47+
(list_marker_plus)
48+
(list_marker_minus)
49+
(list_marker_star)
50+
] @list_marker
51+
52+
[
53+
(task_list_marker_unchecked)
54+
(task_list_marker_checked)
55+
] @checkbox
56+
57+
(block_quote) @quote
58+
59+
(pipe_table) @table
60+
]]
61+
)
2162
self.renderers = {
2263
checkbox = require('render-markdown.render.checkbox'),
2364
code = require('render-markdown.render.code'),
@@ -34,7 +75,7 @@ end
3475
---@param root TSNode
3576
---@return render.md.Mark[]
3677
function Handler:parse(root)
37-
self.context:query(root, state.markdown_query, function(capture, info)
78+
self.context:query(root, self.query, function(capture, info)
3879
local renderer = self.renderers[capture]
3980
if renderer ~= nil then
4081
local render = renderer:new(self.marks, self.config, self.context, info)

lua/render-markdown/handler/markdown_inline.lua

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ local list = require('render-markdown.core.list')
44
local log = require('render-markdown.core.log')
55
local state = require('render-markdown.state')
66
local str = require('render-markdown.core.str')
7+
local treesitter = require('render-markdown.core.treesitter')
78

89
---@class render.md.handler.buf.MarkdownInline
910
---@field private marks render.md.Marks
1011
---@field private config render.md.buffer.Config
1112
---@field private context render.md.Context
13+
---@field private query vim.treesitter.Query
1214
local Handler = {}
1315
Handler.__index = Handler
1416

@@ -19,13 +21,28 @@ function Handler.new(buf)
1921
self.marks = list.new_marks()
2022
self.config = state.get(buf)
2123
self.context = Context.get(buf)
24+
self.query = treesitter.parse(
25+
'markdown_inline',
26+
[[
27+
(code_span) @code
28+
29+
(shortcut_link) @shortcut
30+
31+
[
32+
(image)
33+
(email_autolink)
34+
(inline_link)
35+
(full_reference_link)
36+
] @link
37+
]]
38+
)
2239
return self
2340
end
2441

2542
---@param root TSNode
2643
---@return render.md.Mark[]
2744
function Handler:parse(root)
28-
self.context:query(root, state.inline_query, function(capture, info)
45+
self.context:query(root, self.query, function(capture, info)
2946
if capture == 'code' then
3047
self:code(info)
3148
elseif capture == 'shortcut' then

lua/render-markdown/health.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ local state = require('render-markdown.state')
44
local M = {}
55

66
---@private
7-
M.version = '7.2.7'
7+
M.version = '7.2.8'
88

99
function M.check()
1010
M.start('version')

lua/render-markdown/render/quote.lua

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
local Base = require('render-markdown.render.base')
22
local log = require('render-markdown.core.log')
3-
local state = require('render-markdown.state')
3+
local treesitter = require('render-markdown.core.treesitter')
44

55
---@class render.md.render.Quote: render.md.Renderer
66
---@field private quote render.md.Quote
7+
---@field private query vim.treesitter.Query
78
---@field private highlight string
89
local Render = setmetatable({}, Base)
910
Render.__index = Render
@@ -24,14 +25,24 @@ function Render:setup()
2425
return false
2526
end
2627

28+
self.query = treesitter.parse(
29+
'markdown',
30+
[[
31+
[
32+
(block_quote_marker)
33+
(block_continuation)
34+
] @quote_marker
35+
]]
36+
)
37+
2738
local callout = self.context:get_component(self.info)
2839
self.highlight = callout ~= nil and callout.highlight or self.quote.highlight
2940

3041
return true
3142
end
3243

3344
function Render:render()
34-
self.context:query(self.info:get_node(), state.markdown_quote_query, function(capture, info)
45+
self.context:query(self.info:get_node(), self.query, function(capture, info)
3546
if capture == 'quote_marker' then
3647
self:quote_marker(info)
3748
else

lua/render-markdown/render/table.lua

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -302,19 +302,20 @@ function Render:full()
302302
end
303303
end
304304

305-
---@param row render.md.table.Row
306-
---@return integer
307-
local function get_spaces(row)
308-
return math.max(str.spaces('start', row.info.text), row.info.start_col)
309-
end
310-
311305
local first, last = rows[1], rows[#rows]
312306
if not width_equal(first) or not width_equal(last) then
313307
return
314308
end
315309

316-
local spaces = get_spaces(first)
317-
if spaces ~= get_spaces(last) then
310+
---@param info render.md.NodeInfo
311+
---@return integer
312+
local function get_spaces(info)
313+
return math.max(str.spaces('start', info:line('first', 0) or ''), info.start_col)
314+
end
315+
316+
local first_info, last_info = first.info, #rows == 1 and delim.info or last.info
317+
local spaces = get_spaces(first_info)
318+
if spaces ~= get_spaces(last_info) then
318319
return
319320
end
320321

@@ -335,8 +336,7 @@ function Render:full()
335336
})
336337
end
337338

338-
local last_info = #rows == 1 and delim.info or last.info
339-
table_border(first.info, true, { border[1], border[2], border[3] })
339+
table_border(first_info, true, { border[1], border[2], border[3] })
340340
table_border(last_info, false, { border[7], border[8], border[9] })
341341
end
342342

lua/render-markdown/state.lua

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ local configs = {}
1414
---@field file_types string[]
1515
---@field latex render.md.Latex
1616
---@field custom_handlers table<string, render.md.Handler>
17-
---@field markdown_query vim.treesitter.Query
18-
---@field markdown_quote_query vim.treesitter.Query
19-
---@field inline_query vim.treesitter.Query
2017
local M = {}
2118

2219
---@return boolean
@@ -47,11 +44,6 @@ function M.setup(default_config, user_config)
4744
M.file_types = config.file_types
4845
M.latex = config.latex
4946
M.custom_handlers = config.custom_handlers
50-
vim.schedule(function()
51-
M.markdown_query = vim.treesitter.query.parse('markdown', treesitter.queries.markdown)
52-
M.markdown_quote_query = vim.treesitter.query.parse('markdown', treesitter.queries.markdown_quote)
53-
M.inline_query = vim.treesitter.query.parse('markdown_inline', treesitter.queries.inline)
54-
end)
5547
log.setup(config.log_level)
5648
for _, language in ipairs(M.file_types) do
5749
treesitter.inject(language, config.injections[language])

0 commit comments

Comments
 (0)