@@ -3,11 +3,9 @@ local J = {
3
3
}
4
4
5
5
local query = [[
6
- ; If somehow we can group all the attributes into one
7
6
(jsx_opening_element [(jsx_attribute) (comment)] @nojsx)
8
7
9
- ; If somehow we can group all the comments into one
10
- (jsx_expression (comment)) @jsx
8
+ ((jsx_expression (comment)) @jsx)
11
9
12
10
(jsx_expression
13
11
[(object) (call_expression)] @nojsx)
@@ -19,11 +17,59 @@ local query = [[
19
17
[(jsx_fragment) (jsx_element)] @jsx)
20
18
]]
21
19
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
22
27
local 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
25
29
end
26
30
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 ?
27
73
local function capture (parser , range )
28
74
local lang = parser :lang ()
29
75
@@ -33,29 +79,34 @@ local function capture(parser, range)
33
79
34
80
local Q = vim .treesitter .query .parse_query (lang , query )
35
81
36
- local lines , group
82
+ local id , lines = 0 , nil
37
83
38
84
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
49
90
end
50
91
end
51
92
end
52
93
end
53
94
54
- return group == ' jsx' and J .comment
95
+ return Q . captures [ id ] == ' jsx' and J .comment
55
96
end
56
97
98
+ --- Calculates the `jsx` commentstring
99
+ --- @param ctx Ctx
100
+ --- @return string ?
57
101
function 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 )
59
110
60
111
if not ok then
61
112
return
@@ -71,15 +122,15 @@ function J.calculate(ctx)
71
122
-- This is for `markdown` which embeds multiple `tsx` blocks
72
123
for _ , child in pairs (P :children ()) do
73
124
if child :contains (rng ) then
74
- local captured = capture ( child , ctx .range )
125
+ local _ , captured = pcall ( capture , child , ctx .range )
75
126
if captured then
76
127
return captured
77
128
end
78
129
end
79
130
end
80
131
132
+ -- This is for `tsx` itself
81
133
if P :contains (rng ) then
82
- -- This is for `tsx` itself
83
134
return capture (P , ctx .range )
84
135
end
85
136
end
0 commit comments