@@ -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,60 @@ 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
27
+ --- @return boolean
22
28
local 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
25
30
end
26
31
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
27
74
local function capture (parser , range )
28
75
local lang = parser :lang ()
29
76
@@ -33,55 +80,55 @@ local function capture(parser, range)
33
80
34
81
local Q = vim .treesitter .query .parse_query (lang , query )
35
82
36
- local lines , group
83
+ local id , lines = 0 , nil
37
84
38
85
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
47
89
if not lines or region < lines then
48
- lines , group = region , Q . captures [ id ]
90
+ id , lines = section . id , region
49
91
end
50
92
end
51
93
end
52
94
end
53
95
54
- return group == ' jsx' and J . comment
96
+ return Q . captures [ id ] == ' jsx'
55
97
end
56
98
99
+ --- Calculates the `jsx` commentstring
100
+ --- @param ctx Ctx
101
+ --- @return string ?
57
102
function 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 )
59
111
60
112
if not ok then
61
113
return
62
114
end
63
115
64
- local rng = {
116
+ local range = {
65
117
ctx .range .srow - 1 ,
66
118
ctx .range .scol ,
67
119
ctx .range .erow - 1 ,
68
120
ctx .range .ecol ,
69
121
}
70
122
71
123
-- 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
78
127
end
79
128
end
80
129
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
85
132
end
86
133
87
134
return J
0 commit comments