@@ -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 , 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
27
73
local function capture (parser , range )
28
74
local lang = parser :lang ()
29
75
@@ -33,55 +79,55 @@ 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
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
47
88
if not lines or region < lines then
48
- lines , group = region , Q . captures [ id ]
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'
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 , tree = pcall (vim .treesitter .get_parser , buf , trees [filetype ] or filetype )
59
110
60
111
if not ok then
61
112
return
62
113
end
63
114
64
- local rng = {
115
+ local range = {
65
116
ctx .range .srow - 1 ,
66
117
ctx .range .scol ,
67
118
ctx .range .erow - 1 ,
68
119
ctx .range .ecol ,
69
120
}
70
121
71
122
-- 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
78
126
end
79
127
end
80
128
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
85
131
end
86
132
87
133
return J
0 commit comments