1
+ local Config = require (" kulala.config" )
1
2
local DB = require (" kulala.db" )
2
3
local Diagnostics = require (" kulala.cmd.diagnostics" )
3
4
local FS = require (" kulala.utils.fs" )
@@ -9,7 +10,9 @@ local Table = require("kulala.utils.table")
9
10
local M = {}
10
11
11
12
--- @class DocumentRequest
13
+ --- @field shared DocumentRequest
12
14
--- @field metadata table< {name : string , value : string } >
15
+ --- @field variables table< {name : string , value : string | number | boolean } >
13
16
--- @field comments string[]
14
17
---
15
18
--- @field method string
@@ -53,7 +56,10 @@ local M = {}
53
56
54
57
--- @type DocumentRequest
55
58
local default_document_request = {
59
+ --- @diagnostic disable-next-line : missing-fields
60
+ shared = {},
56
61
metadata = {},
62
+ variables = {},
57
63
comments = {},
58
64
method = " " ,
59
65
url = " " ,
@@ -179,15 +185,17 @@ local function parse_redirect_response(request, line)
179
185
})
180
186
end
181
187
182
- -- Variable
183
188
-- Variables are defined as `@variable_name=value`
184
189
-- The value can be a string, a number or boolean
185
- local function parse_variables (variables , line )
190
+ local function parse_variables (request , variables , line )
186
191
local variable_name , variable_value = line :match (" ^@([%w_]+)%s*=%s*(.*)$" )
187
192
if variable_name and variable_value then
188
193
-- remove the @ symbol from the variable name
189
194
variable_name = variable_name :sub (1 )
190
195
variables [variable_name ] = variable_value
196
+
197
+ request .variables [variable_name ] = variable_value
198
+ if Config .options .variables_scope == " document" then request .shared .variables [variable_name ] = variable_value end
191
199
end
192
200
end
193
201
@@ -361,7 +369,7 @@ local function parse_run_command(requests, imported_requests, variables, request
361
369
end )
362
370
363
371
vim .iter (vim .split (variables_to_replace or " " , " ,%s*" )):each (function (variable )
364
- parse_variables (variables , variable )
372
+ parse_variables (request , variables , variable )
365
373
end )
366
374
end
367
375
@@ -409,7 +417,10 @@ function parse_document(lines, path)
409
417
410
418
if not content_lines then return end
411
419
412
- local variables = {}
420
+ local shared = vim .deepcopy (default_document_request )
421
+ shared .url = nil
422
+
423
+ local variables = {} -- TODO: remove
413
424
local requests = {}
414
425
local imported_requests = {}
415
426
local blocks = split_content_by_blocks (content_lines , line_offset )
@@ -426,6 +437,7 @@ function parse_document(lines, path)
426
437
request .end_line = block .end_lnum
427
438
request .name = block .name
428
439
request .file = path or vim .fn .fnamemodify (vim .fn .bufname (DB .get_current_buffer ()), " :p" )
440
+ request .shared = shared
429
441
430
442
for relative_linenr , line in ipairs (block .lines ) do
431
443
local lnum = request .start_line + relative_linenr
@@ -454,7 +466,7 @@ function parse_document(lines, path)
454
466
elseif is_prerequest_handler_script_inline then
455
467
request .scripts .pre_request .priority = request .scripts .pre_request .priority or " inline"
456
468
table.insert (request .scripts .pre_request .inline , line )
457
- -- we're still in(/before) the request line and we have a pre-request inline handler script
469
+ -- we're still in(/before) the request line and we have a pre-request inline handler script
458
470
elseif is_request_line and line :match (" ^< %{%%$" ) then
459
471
is_prerequest_handler_script_inline = true
460
472
-- we're still in(/before) the request line and we have a pre-request file handler script
@@ -476,7 +488,7 @@ function parse_document(lines, path)
476
488
local scriptfile = line :match (" ^> (.*)$" )
477
489
table.insert (request .scripts .post_request .files , scriptfile )
478
490
elseif line :match (" ^@([%w_]+)" ) then
479
- parse_variables (variables , line )
491
+ parse_variables (request , variables , line )
480
492
elseif is_body_section then
481
493
parse_body (request , line , lnum )
482
494
elseif not is_request_line and line :match (" ^%s*/.+" ) then
@@ -502,13 +514,15 @@ function parse_document(lines, path)
502
514
infer_headers_from_body (request )
503
515
end
504
516
505
- if request .url and # request .url > 0 then
517
+ if request .name == " Shared" or request .name == " Shared each" then
518
+ shared = request
519
+ shared .url = # shared .url > 0 and shared .url or nil
520
+ elseif request .url and # request .url > 0 then
506
521
table.insert (requests , request )
507
522
elseif # request .nested_requests > 0 then
508
523
vim .iter (request .nested_requests or {}):each (function (r )
509
524
r .metadata = vim .tbl_extend (" force" , r .metadata , request .metadata )
510
- r .start_line = request .start_line
511
- r .end_line = request .end_line
525
+ r .start_line , r .end_line = request .start_line , request .end_line
512
526
end )
513
527
vim .list_extend (requests , request .nested_requests )
514
528
end
@@ -533,16 +547,58 @@ M.get_document = function(lines, path)
533
547
return unpack (result )
534
548
end
535
549
550
+ local function apply_shared_data (shared , request )
551
+ local request_metadata = vim
552
+ .iter (request .metadata )
553
+ :map (function (metadata )
554
+ return metadata .name
555
+ end )
556
+ :totable ()
557
+
558
+ vim .iter (shared .metadata ):each (function (metadata )
559
+ if not vim .tbl_contains (request_metadata , metadata .name ) then table.insert (request .metadata , metadata ) end
560
+ end )
561
+
562
+ vim .iter (shared .variables ):each (function (k , v )
563
+ if not request .variables [k ] then request .variables [k ] = v end
564
+ end )
565
+
566
+ return request
567
+ end
568
+
569
+ local function is_runnable (request )
570
+ local pre_scripts = request .scripts .pre_request
571
+ return request .url or # pre_scripts .inline + # pre_scripts .files > 0 or # request .nested_requests > 0
572
+ end
573
+
536
574
local function expand_nested_requests (requests , lnum )
537
575
requests = vim .islist (requests ) and requests or { requests }
538
576
539
577
local expanded = {}
578
+ local shared = requests [1 ].shared
579
+
580
+ if not requests [1 ].name :match (" Shared" ) and is_runnable (shared ) then
581
+ if shared .name == " Shared each" then
582
+ local requests_ = vim .deepcopy (requests )
583
+ requests = {}
584
+
585
+ vim .iter (requests_ ):each (function (request )
586
+ table.insert (requests , shared )
587
+ table.insert (requests , request )
588
+ end )
589
+ else
590
+ table.insert (requests , 1 , shared )
591
+ end
592
+ end
540
593
541
594
vim .iter (requests ):each (function (request )
595
+ request = apply_shared_data (shared , request )
596
+
542
597
vim .iter (request .nested_requests ):each (function (nested_request )
543
598
nested_request .show_icon_line_number = lnum or nested_request .show_icon_line_number
544
599
vim .list_extend (expanded , expand_nested_requests (nested_request , nested_request .show_icon_line_number ))
545
600
end )
601
+
546
602
table.insert (expanded , request )
547
603
end )
548
604
0 commit comments