@@ -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 , section , sections = 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 boolean
2773local function capture (parser , range )
2874 local lang = parser :lang ()
2975
@@ -33,55 +79,55 @@ 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
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
4788 if not lines or region < lines then
48- lines , group = region , Q . captures [ id ]
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'
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 , tree = pcall (vim .treesitter .get_parser , buf , trees [filetype ] or filetype )
59110
60111 if not ok then
61112 return
62113 end
63114
64- local rng = {
115+ local range = {
65116 ctx .range .srow - 1 ,
66117 ctx .range .scol ,
67118 ctx .range .erow - 1 ,
68119 ctx .range .ecol ,
69120 }
70121
71122 -- This is for `markdown` which embeds multiple `tsx` blocks
72- for _ , child in pairs (P :children ()) do
73- if child :contains (rng ) then
74- local captured = capture (child , ctx .range )
75- if captured then
76- return captured
77- end
123+ for _ , child in pairs (tree :children ()) do
124+ if child :contains (range ) and capture (child , ctx .range ) then
125+ return J .comment
78126 end
79127 end
80128
81- if P :contains (rng ) then
82- -- This is for `tsx` itself
83- return capture (P , ctx .range )
84- end
129+ -- This is for `tsx` itself
130+ return (tree :contains (range ) and capture (tree , ctx .range )) and J .comment
85131end
86132
87133return J
0 commit comments