@@ -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,60 @@ 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
27+ --- @return boolean
2228local function is_jsx (lang )
23- -- Name of the treesitter parsers that supports jsx syntax
24- return lang == ' tsx' or lang == ' javascript'
29+ return lang == trees .typescriptreact or lang == trees .javascriptreact
2530end
2631
32+ -- This function is a workaround for `+` treesitter quantifier
33+ -- which is currently not supported by neovim (wip: https://github.com/neovim/neovim/pull/15330)
34+ -- because of this we can't query consecutive comment or attributes nodes,
35+ -- and group them as single range, hence this function
36+ --- @param q table
37+ --- @param tree table
38+ --- @param parser table
39+ --- @param range CRange
40+ --- @return table
41+ local function normalize (q , tree , parser , range )
42+ local prev , section , sections = nil , 0 , {}
43+
44+ for id , node in q :iter_captures (tree :root (), parser :source (), range .srow - 1 , range .erow ) do
45+ if id ~= prev then
46+ section = section + 1
47+ end
48+
49+ local srow , _ , erow = node :range ()
50+ local key = string.format (' %s.%s' , id , section )
51+ if sections [key ] == nil then
52+ sections [key ] = { id = id , range = { srow = srow , erow = erow } }
53+ else
54+ -- storing the smallest starting row and biggest ending row
55+ local r = sections [key ].range
56+ if srow < r .srow then
57+ sections [key ].range .srow = srow
58+ end
59+ if erow > r .erow then
60+ sections [key ].range .erow = erow
61+ end
62+ end
63+
64+ prev = id
65+ end
66+
67+ return sections
68+ end
69+
70+ --- Runs the query and returns the commentstring by checking the cursor range
71+ --- @param parser table
72+ --- @param range CRange
73+ --- @return boolean
2774local function capture (parser , range )
2875 local lang = parser :lang ()
2976
@@ -33,55 +80,55 @@ local function capture(parser, range)
3380
3481 local Q = vim .treesitter .query .parse_query (lang , query )
3582
36- local lines , group
83+ local id , lines = 0 , nil
3784
3885 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
86+ for _ , section in pairs (normalize (Q , tree , parser , range )) do
87+ if section .range .srow <= range .srow - 1 and section .range .erow >= range .erow - 1 then
88+ local region = section .range .erow - section .range .srow
4789 if not lines or region < lines then
48- lines , group = region , Q . captures [ id ]
90+ id , lines = section . id , region
4991 end
5092 end
5193 end
5294 end
5395
54- return group == ' jsx' and J . comment
96+ return Q . captures [ id ] == ' jsx'
5597end
5698
99+ --- Calculates the `jsx` commentstring
100+ --- @param ctx Ctx
101+ --- @return string ?
57102function J .calculate (ctx )
58- local ok , P = pcall (vim .treesitter .get_parser )
103+ local buf = vim .api .nvim_get_current_buf ()
104+ local filetype = vim .api .nvim_buf_get_option (buf , ' filetype' )
105+
106+ -- NOTE:
107+ -- `get_parser` panics for `{type,java}scriptreact` filetype
108+ -- bcz their parser's name is different from their filetype
109+ -- Maybe report the issue to `nvim-treesitter` or core(?)
110+ local ok , tree = pcall (vim .treesitter .get_parser , buf , trees [filetype ] or filetype )
59111
60112 if not ok then
61113 return
62114 end
63115
64- local rng = {
116+ local range = {
65117 ctx .range .srow - 1 ,
66118 ctx .range .scol ,
67119 ctx .range .erow - 1 ,
68120 ctx .range .ecol ,
69121 }
70122
71123 -- 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
124+ for _ , child in pairs (tree :children ()) do
125+ if child :contains (range ) and capture (child , ctx .range ) then
126+ return J .comment
78127 end
79128 end
80129
81- if P :contains (rng ) then
82- -- This is for `tsx` itself
83- return capture (P , ctx .range )
84- end
130+ -- This is for `tsx` itself
131+ return (tree :contains (range ) and capture (tree , ctx .range )) and J .comment
85132end
86133
87134return J
0 commit comments