@@ -19,11 +19,11 @@ local library_query = {
19
19
--- @param file string ファイルパス
20
20
--- @return string | nil クエリ
21
21
function M .load_query_from_file (file )
22
- local cache = {}
22
+ local query_cache = {}
23
23
24
24
local function load_query_from_file (file )
25
- if cache [file ] ~= nil then
26
- return cache [file ]
25
+ if query_cache [file ] ~= nil then
26
+ return query_cache [file ]
27
27
end
28
28
29
29
local f = io.open (file , " r" )
@@ -34,7 +34,7 @@ function M.load_query_from_file(file)
34
34
local query = f :read (" *a" )
35
35
f :close ()
36
36
37
- cache [file ] = query
37
+ query_cache [file ] = query
38
38
return query
39
39
end
40
40
@@ -71,13 +71,19 @@ local function calculate_node_depth(node)
71
71
end
72
72
73
73
--- Treesitterパーサーをセットアップしてキーにマッチするノードを取得する関数
74
- --- @param bufnr number 文言ファイルのバッファ番号
74
+ --- @param source integer | string バッファ番号 or ソース
75
75
--- @param keys string[] キー
76
76
--- @return TSNode | nil , string | nil
77
- function M .get_node_for_key (bufnr , keys )
77
+ function M .get_node_for_key (source , keys )
78
78
local ts = vim .treesitter
79
79
80
- local parser = ts .get_parser (bufnr , " json" )
80
+ local parser = (function ()
81
+ if type (source ) == " string" then
82
+ return ts .get_string_parser (source , " json" )
83
+ else
84
+ return ts .get_parser (source )
85
+ end
86
+ end )()
81
87
local tree = parser :parse ()[1 ]
82
88
local root = tree :root ()
83
89
@@ -86,15 +92,15 @@ function M.get_node_for_key(bufnr, keys)
86
92
local query = ts .query .parse (" json" , [[
87
93
(pair
88
94
key: (string) @key (#eq? @key "\"]] .. k .. [[ \"")
89
- value: [(object)(string)] @value
95
+ value: [(object)(array)( string)] @value
90
96
)
91
97
]] )
92
98
93
99
local key_node = nil
94
100
local key_node_depth = 9999
95
101
local value_node = nil
96
102
local value_node_depth = 9999
97
- for id , node , _ in query :iter_captures (json_node , bufnr ) do
103
+ for id , node , _ in query :iter_captures (json_node , source ) do
98
104
local name = query .captures [id ]
99
105
local depth = calculate_node_depth (node )
100
106
if name == " key" and depth < key_node_depth then
@@ -164,20 +170,20 @@ end
164
170
165
171
--- t関数の取得に関する情報を解析する
166
172
--- @param target_node TSNode t 関数取得のノード
167
- --- @param bufnr integer バッファ番号
173
+ --- @param source ( integer | string ) バッファ番号 or ソース
168
174
--- @param query vim.treesitter.Query クエリ
169
175
--- @return GetTDetail | nil
170
- local function parse_get_t (target_node , bufnr , query )
176
+ local function parse_get_t (target_node , source , query )
171
177
local namespace = " "
172
178
local key_prefix = " "
173
179
174
- for id , node , _ in query :iter_captures (target_node , bufnr , 0 , - 1 ) do
180
+ for id , node , _ in query :iter_captures (target_node , source , 0 , - 1 ) do
175
181
local name = query .captures [id ]
176
182
177
183
if name == " i18n.namespace" then
178
- namespace = vim .treesitter .get_node_text (node , bufnr )
184
+ namespace = vim .treesitter .get_node_text (node , source )
179
185
elseif name == " i18n.key_prefix" then
180
- key_prefix = vim .treesitter .get_node_text (node , bufnr )
186
+ key_prefix = vim .treesitter .get_node_text (node , source )
181
187
end
182
188
end
183
189
@@ -199,30 +205,30 @@ end
199
205
200
206
--- t関数の呼び出しに関する情報を解析する
201
207
--- @param target_node TSNode t 関数呼び出しのノード
202
- --- @param bufnr integer バッファ番号
208
+ --- @param source ( integer | string ) バッファ番号 or ソース
203
209
--- @param query vim.treesitter.Query クエリ
204
210
--- @return CallTDetail | nil
205
- local function parse_call_t (target_node , bufnr , query )
211
+ local function parse_call_t (target_node , source , query )
206
212
local key = nil
207
213
local key_node = nil
208
214
local key_arg_node = nil
209
215
local namespace = nil
210
216
local key_prefix = nil
211
217
212
- for id , node , _ in query :iter_captures (target_node , bufnr , 0 , - 1 ) do
218
+ for id , node , _ in query :iter_captures (target_node , source , 0 , - 1 ) do
213
219
local name = query .captures [id ]
214
220
215
221
-- t関数の呼び出しがネストしている場合があるため、最初に見つかったものを採用する
216
222
-- そのため key = ke or ... のような形にしている
217
223
if name == " i18n.key" then
218
- key = key or vim .treesitter .get_node_text (node , bufnr )
224
+ key = key or vim .treesitter .get_node_text (node , source )
219
225
key_node = key_node or node
220
226
elseif name == " i18n.key_arg" then
221
227
key_arg_node = key_arg_node or node
222
228
elseif name == " i18n.namespace" then
223
- namespace = namespace or vim .treesitter .get_node_text (node , bufnr )
229
+ namespace = namespace or vim .treesitter .get_node_text (node , source )
224
230
elseif name == " i18n.key_prefix" then
225
- key_prefix = key_prefix or vim .treesitter .get_node_text (node , bufnr )
231
+ key_prefix = key_prefix or vim .treesitter .get_node_text (node , source )
226
232
end
227
233
end
228
234
@@ -239,6 +245,14 @@ local function parse_call_t(target_node, bufnr, query)
239
245
}
240
246
end
241
247
248
+ --- t関数を含むノードを検索する
249
+ --- @param bufnr integer バッファ番号
250
+ --- @return FindTExpressionResultItem[]
251
+ function M .find_call_t_expressions_from_buf (bufnr )
252
+ local workspace_dir = utils .get_workspace_root (bufnr )
253
+ return M .find_call_t_expressions (bufnr , utils .detect_library (workspace_dir ))
254
+ end
255
+
242
256
--- @class FindTExpressionResultItem
243
257
--- @field node TSNode t 関数のノード
244
258
--- @field key_node TSNode t 関数のキーのノード
@@ -249,24 +263,39 @@ end
249
263
--- @field namespace ? string t 関数の namespace
250
264
251
265
--- t関数を含むノードを検索する
252
- --- @param bufnr integer バッファ番号
266
+ --- @param source integer | string バッファ番号 or ソース
267
+ --- @param lib ? string ライブラリ
268
+ --- @param lang ? string 言語
253
269
--- @return FindTExpressionResultItem[]
254
- function M .find_call_t_expressions (bufnr )
255
- local ok , parser = pcall (vim .treesitter .get_parser , bufnr )
270
+ function M .find_call_t_expressions (source , lib , lang )
271
+ local ok , parser = pcall (function ()
272
+ if type (source ) == " string" then
273
+ vim .validate ({ lang = { lang , " string" , true } })
274
+ if lang == nil then
275
+ error (" lang is required when source is string" )
276
+ end
277
+ return vim .treesitter .get_string_parser (source , lang )
278
+ else
279
+ return vim .treesitter .get_parser (source )
280
+ end
281
+ end )
256
282
if not ok then
257
283
return {}
258
284
end
285
+
259
286
local tree = parser :parse ()[1 ]
260
287
local root_node = tree :root ()
261
- local language = parser :lang ()
288
+ local language = lang or parser :lang ()
262
289
263
290
if not vim .tbl_contains ({ " javascript" , " typescript" , " jsx" , " tsx" }, language ) then
264
291
return {}
265
292
end
266
293
267
- local library = utils .detect_library (bufnr ) or utils .Library .I18Next
268
294
local query_str = " "
269
- for _ , query_file in ipairs (library_query [library ][language ] or library_query [library ][" *" ]) do
295
+ if type (library_query [lib ]) ~= " table" then
296
+ return {}
297
+ end
298
+ for _ , query_file in ipairs (library_query [lib ][language ] or library_query [lib ][" *" ]) do
270
299
local str = M .load_query_from_file (query_file )
271
300
if str and type (str ) == " string" and str ~= " " then
272
301
query_str = query_str .. " \n " .. str
@@ -303,7 +332,7 @@ function M.find_call_t_expressions(bufnr)
303
332
--- @type FindTExpressionResultItem[]
304
333
local result = {}
305
334
306
- for id , node , _ in query :iter_captures (root_node , bufnr ) do
335
+ for id , node , _ in query :iter_captures (root_node , source ) do
307
336
local name = query .captures [id ]
308
337
309
338
-- 現在のスコープから抜けたかどうかを判定する
@@ -313,7 +342,7 @@ function M.find_call_t_expressions(bufnr)
313
342
end
314
343
315
344
if name == " i18n.get_t" then
316
- local get_t_detail = parse_get_t (node , bufnr , query )
345
+ local get_t_detail = parse_get_t (node , source , query )
317
346
if get_t_detail then
318
347
-- 同一のスコープ内で get_t が呼ばれた場合はスコープを上書きする形になるように、一度 leave_scope してから enter_scope する
319
348
if get_t_detail .scope_node == current_scope ().scope_node then
@@ -323,7 +352,7 @@ function M.find_call_t_expressions(bufnr)
323
352
end
324
353
elseif name == " i18n.call_t" then
325
354
local scope = current_scope ()
326
- local call_t_detail = parse_call_t (node , bufnr , query )
355
+ local call_t_detail = parse_call_t (node , source , query )
327
356
328
357
if call_t_detail == nil then
329
358
goto continue
363
392
--- @return boolean ok カーソルが t 関数の引数内にあるかどうか
364
393
--- @return FindTExpressionResultItem | nil result カーソルが t 関数の引数内にある場合は t 関数の情報
365
394
function M .check_cursor_in_t_argument (bufnr , position )
366
- local t_calls = M .find_call_t_expressions (bufnr )
395
+ local t_calls = M .find_call_t_expressions_from_buf (bufnr )
367
396
368
397
for _ , t_call in ipairs (t_calls ) do
369
398
local key_arg_node = t_call .key_arg_node
0 commit comments