@@ -3,11 +3,9 @@ local J = {
33}
44
55local query = [[
6- ; If somehow we can group all the attributes into one
76 (jsx_opening_element [(jsx_attribute) (comment)] @nojsx)
87
9- ; If somehow we can group all the comments into one
10- (jsx_expression (comment)) @jsx
8+ ((jsx_expression (comment)) @jsx)
119
1210 (jsx_expression
1311 [(object) (call_expression)] @nojsx)
@@ -19,11 +17,59 @@ local query = [[
1917 [(jsx_fragment) (jsx_element)] @jsx)
2018]]
2119
20+ local trees = {
21+ typescriptreact = ' tsx' ,
22+ javascriptreact = ' javascript' ,
23+ }
24+
25+ --- Checks whether parser's language matches the filetype that supports jsx syntax
26+ --- @param lang string
2227local function is_jsx (lang )
23- -- Name of the treesitter parsers that supports jsx syntax
24- return lang == ' tsx' or lang == ' javascript'
28+ return lang == trees .typescriptreact or lang == trees .javascriptreact
2529end
2630
31+ -- This function is a workaround for `+` treesitter quantifier
32+ -- which is currently not supported by neovim (wip: https://github.com/neovim/neovim/pull/15330)
33+ -- because of this we can't query consecutive comment or attributes nodes,
34+ -- and group them as single range, hence this function
35+ --- @param q table
36+ --- @param tree table
37+ --- @param parser table
38+ --- @param range CRange
39+ --- @return table
40+ local function normalize (q , tree , parser , range )
41+ local prev , sections , section = nil , {}, 0
42+
43+ for id , node in q :iter_captures (tree :root (), parser :source (), range .srow - 1 , range .erow ) do
44+ if id ~= prev then
45+ section = section + 1
46+ end
47+
48+ local srow , _ , erow = node :range ()
49+ local key = string.format (' %s.%s' , id , section )
50+ if sections [key ] == nil then
51+ sections [key ] = { id = id , range = { srow = srow , erow = erow } }
52+ else
53+ -- storing the smallest starting row and biggest ending row
54+ local r = sections [key ].range
55+ if srow < r .srow then
56+ sections [key ].range .srow = srow
57+ end
58+ if erow > r .erow then
59+ sections [key ].range .erow = erow
60+ end
61+ end
62+
63+ prev = id
64+ end
65+
66+ return sections
67+ end
68+
69+ --- Runs the query and returns the commentstring by checking the cursor range
70+ --- @param parser table
71+ --- @param range CRange
72+ --- @return string ?
2773local function capture (parser , range )
2874 local lang = parser :lang ()
2975
@@ -33,29 +79,34 @@ local function capture(parser, range)
3379
3480 local Q = vim .treesitter .query .parse_query (lang , query )
3581
36- local lines , group
82+ local id , lines = 0 , nil
3783
3884 for _ , tree in ipairs (parser :trees ()) do
39- for id , node in Q :iter_captures (tree :root (), parser :source (), range .srow - 1 , range .erow ) do
40- local srow , _ , erow = node :range ()
41- -- print(Q.captures[id])
42- -- print(srow, range.srow - 1)
43- -- print(erow, range.erow - 1)
44- -- print(srow <= range.srow - 1 and erow >= range.erow - 1)
45- if srow <= range .srow - 1 and erow >= range .erow - 1 then
46- local region = erow - srow
47- if not lines or region < lines then
48- lines , group = region , Q .captures [id ]
85+ for _ , section in pairs (normalize (Q , tree , parser , range )) do
86+ if section .range .srow <= range .srow - 1 and section .range .erow >= range .erow - 1 then
87+ local region = section .range .erow - section .range .srow
88+ if lines == nil or region < lines then
89+ id , lines = section .id , region
4990 end
5091 end
5192 end
5293 end
5394
54- return group == ' jsx' and J .comment
95+ return Q . captures [ id ] == ' jsx' and J .comment
5596end
5697
98+ --- Calculates the `jsx` commentstring
99+ --- @param ctx Ctx
100+ --- @return string ?
57101function J .calculate (ctx )
58- local ok , P = pcall (vim .treesitter .get_parser )
102+ local buf = vim .api .nvim_get_current_buf ()
103+ local filetype = vim .api .nvim_buf_get_option (buf , ' filetype' )
104+
105+ -- NOTE:
106+ -- `get_parser` panics for `{type,java}scriptreact` filetype
107+ -- bcz their parser's name is different from their filetype
108+ -- Maybe report the issue to `nvim-treesitter` or core(?)
109+ local ok , P = pcall (vim .treesitter .get_parser , buf , trees [filetype ] or filetype )
59110
60111 if not ok then
61112 return
@@ -71,15 +122,15 @@ function J.calculate(ctx)
71122 -- This is for `markdown` which embeds multiple `tsx` blocks
72123 for _ , child in pairs (P :children ()) do
73124 if child :contains (rng ) then
74- local captured = capture ( child , ctx .range )
125+ local _ , captured = pcall ( capture , child , ctx .range )
75126 if captured then
76127 return captured
77128 end
78129 end
79130 end
80131
132+ -- This is for `tsx` itself
81133 if P :contains (rng ) then
82- -- This is for `tsx` itself
83134 return capture (P , ctx .range )
84135 end
85136end
0 commit comments