Skip to content

Commit 2fec5f9

Browse files
feat: pre-script & handler-scripts
1 parent 09358a3 commit 2fec5f9

File tree

5 files changed

+120
-36
lines changed

5 files changed

+120
-36
lines changed

lua/rest-nvim/client/curl.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,11 @@ end
151151

152152
---Execute an HTTP request using cURL
153153
---return return nil if execution failed
154-
---@param request Request_ Request data to be passed to cURL
154+
---@param request Request Request data to be passed to cURL
155155
---@return table? info The request information (url, method, headers, body, etc)
156156
function client.request_(request)
157-
local info = {}
157+
-- write to `Context.response` without altering the reference
158+
local info = request.context.response
158159
if not found_curl then
159160
---@diagnostic disable-next-line need-check-nil
160161
logger.error("lua-curl could not be found, therefore the cURL client will not work.")

lua/rest-nvim/context.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ local M = {}
77
---@class Context
88
---@field vars table<string,string>
99
---@field files string[]
10+
---@field request? Request
11+
---@field response? any
1012
local Context = {}
1113
Context.__index = Context
1214

@@ -40,10 +42,12 @@ local rest_variables = {
4042

4143
---@return Context
4244
function Context:new()
45+
---@type Context
4346
local obj = {
4447
__index = self,
4548
vars = {},
4649
files = {},
50+
response = {}, -- create response table here to pass the reference first
4751
}
4852
setmetatable(obj, self)
4953
return obj

lua/rest-nvim/parser/init.lua

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -153,36 +153,67 @@ end
153153

154154
---@param node TSNode
155155
---@param source Source
156-
---@param context Context
157-
---@return function
158-
function M.parse_script(node, source, context)
156+
---@return string str
157+
local function parse_script(node, source)
159158
vim.validate({ node = utils.ts_node_spec(node, "script") })
160159
local str = vim.treesitter.get_node_text(node, source):sub(3,-3)
161-
return script.load(str, context)
160+
return str
162161
end
163162

164163
---@param script_node TSNode
165164
---@param source Source
166165
---@param context Context
167166
function M.parse_pre_request_script(script_node, source, context)
168167
local node = assert(script_node:named_child(0))
169-
M.parse_script(node, source, context)()
168+
local str = parse_script(node, source)
169+
script.load_prescript(str, context)()
170170
end
171171

172172
---@param handler_node TSNode
173173
---@param source Source
174174
---@param context Context
175175
function M.parse_request_handler(handler_node, source, context)
176176
local node = assert(handler_node:named_child(0))
177-
return M.parse_script(node, source, context)
177+
local str = parse_script(node, source)
178+
return script.load_handler(str, context)
179+
end
180+
181+
---@param node TSNode
182+
---@param kind? string[]
183+
---@return TSNode[] siblings
184+
local function collect_prev_siblings(node, kind)
185+
local siblings = {}
186+
local n = node:prev_named_sibling()
187+
while n and n:type() ~= "request_separator" do
188+
if not kind or vim.tbl_contains(kind, n:type()) then
189+
table.insert(siblings, 0, n)
190+
end
191+
n = n:prev_named_sibling()
192+
end
193+
return siblings
194+
end
195+
196+
---@param node TSNode
197+
---@param kind? string[]
198+
---@return TSNode[] siblings
199+
local function collect_next_siblings(node, kind)
200+
local siblings = {}
201+
local n = node:next_named_sibling()
202+
while n and n:type() ~= "request_separator" do
203+
if not kind or vim.tbl_contains(kind, n:type()) then
204+
table.insert(siblings, n)
205+
end
206+
n = n:next_named_sibling()
207+
end
208+
return siblings
178209
end
179210

180211
---Parse the request node and create Request object. Returns `nil` if parsing
181212
---failed.
182213
---@param req_node TSNode Tree-sitter request node
183214
---@param source Source
184215
---@param context? Context
185-
---@return Request_|nil
216+
---@return Request|nil
186217
function M.parse(req_node, source, context)
187218
context = context or Context:new()
188219
-- request should not include error
@@ -206,14 +237,16 @@ function M.parse(req_node, source, context)
206237
context,
207238
config.encode_url and utils.escape or nil
208239
)
209-
local pre_req_scripts = req_node:field("pre_request_script")
210-
for _, script_node in ipairs(pre_req_scripts) do
240+
241+
local pre_script_nodes = collect_prev_siblings(req_node, {"pre_request_script"})
242+
for _, script_node in ipairs(pre_script_nodes) do
211243
M.parse_pre_request_script(script_node, source, context)
212244
end
213-
local handlers = vim.iter(req_node:field("handler_script")):map(function (node)
245+
local handler_nodes = collect_next_siblings(req_node, {"res_handler_script"})
246+
local handlers = vim.iter(handler_nodes):map(function (node)
214247
return M.parse_request_handler(node, source, context)
215248
end):totable()
216-
---@type Request_
249+
---@type Request
217250
return {
218251
context = context,
219252
method = method,

lua/rest-nvim/request.lua

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ local utils = require("rest-nvim.utils")
77
local logger = require("rest-nvim.logger")
88
local config = require("rest-nvim.config")
99

10-
---@class Request_
10+
---@class Request
1111
---@field context Context
1212
---@field name? string The request identifier
1313
---@field method string The request method
@@ -17,12 +17,13 @@ local config = require("rest-nvim.config")
1717
---@field body? ReqBody
1818
---@field handlers fun()[]
1919

20-
---@type Request_|nil
20+
---@type Request|nil
2121
local rest_nvim_last_request = nil
2222

23-
---@param req Request_
23+
---@param req Request
2424
---@return boolean ok
2525
local function run_request(req)
26+
logger.debug("run_request")
2627
local client = require("rest-nvim.client.curl")
2728
rest_nvim_last_request = req
2829

@@ -32,11 +33,13 @@ local function run_request(req)
3233
logger.error("request failed")
3334
return false
3435
end
36+
logger.debug("request success")
3537

3638
-- run request handler scripts
37-
-- TODO: run them with response info
3839
vim.iter(req.handlers):each(function (f) f() end)
3940

41+
logger.debug("handler end")
42+
4043
-- update result UI
4144
local result = require("rest-nvim.result")
4245
local result_buf = result.get_or_create_buf()
@@ -47,6 +50,7 @@ end
4750
---run request in current cursor position
4851
---@return boolean ok
4952
function M.run()
53+
logger.info("starting request")
5054
local req_node = parser.get_cursor_request_node()
5155
if not req_node then
5256
logger.error("failed to find request at cursor position")

lua/rest-nvim/script.lua

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,66 +6,108 @@ local M = {}
66

77
-- TODO: fill script environment
88

9+
---@class RestEnvRequestVariables
10+
---@field set fun(key:string,value:string)
11+
---@field get fun(key:string):string
12+
13+
---@param ctx Context
14+
---@retrun RestPreScriptEnv
15+
function M.create_prescript_env(ctx)
16+
---@class RestPreScriptEnv
17+
local env = {
18+
---@class RestPreScriptEnvRequest
19+
request = {
20+
---@type RestEnvRequestVariables
21+
variables = {
22+
---sets request-local variable
23+
set = function (key, value)
24+
ctx:set(key, value)
25+
end,
26+
---retrieves variable in current request scope
27+
get = function (key)
28+
return ctx:resolve(key)
29+
end,
30+
}
31+
},
32+
vim = vim
33+
}
34+
return env
35+
end
36+
937
---@param ctx Context
10-
---@return ScriptEnv
11-
function M.create_env(ctx)
12-
---@class ScriptEnv
38+
---@return RestHandlerEnv
39+
function M.create_handler_env(ctx)
40+
---@class RestHandlerEnv
1341
local env = {
14-
---@class ScriptEnvClient
42+
---@class RestHandlerEnvClient
1543
client = {
1644
test = function () end,
1745
assert = function () end,
18-
---@class ScriptEnvClientGlobal
46+
---@type RestEnvRequestVariables
1947
global = {
20-
---@param key string
21-
---@param value string
48+
---set global variable (this overwrites `vim.env`)
2249
set = function (key, value)
2350
vim.env[key] = value
2451
end,
25-
---@param key string
26-
---@return string value
52+
---get global variable (return empty string if variable doesn't exist)
2753
get = function (key)
28-
return ctx:resolve(key)
54+
return vim.env[key] or ""
2955
end,
3056
},
3157
},
32-
---@class ScriptEnvRequest
58+
---@class RestHandlerEnvRequest
3359
request = {
3460
body = {},
3561
environment = {},
3662
headers = {},
3763
method = "GET",
3864
url = "",
39-
---@class ScriptEnvRequestVariables
65+
---@type RestEnvRequestVariables
4066
variables = {
4167
---sets request-local variable
42-
---@param key string
43-
---@param value string
4468
set = function (key, value)
4569
ctx:set(key, value)
4670
end,
71+
---retrieves variable in current request scope
72+
get = function (key)
73+
return ctx:resolve(key)
74+
end,
4775
}
4876
},
49-
---@class ScriptEnvResponse
50-
response = nil,
77+
---@class RestHandlerEnvResponse
78+
response = ctx.response,
5179
-- body
5280
-- headers
5381
-- status
5482
-- content_type
83+
vim = vim
5584
}
5685
return env
5786
end
5887

59-
---load script for current context
6088
---@param script string
89+
---@param env table
6190
---@return function
62-
function M.load(script, context)
63-
local env = M.create_env(context)
91+
function M.load(script, env)
6492
local f, error_msg = load(script, "script_variable", "bt", env)
6593
if error_msg then
6694
logger.error(error_msg)
6795
end
6896
return assert(f)
6997
end
7098

99+
---@param script string
100+
---@param ctx Context
101+
---@return function
102+
function M.load_prescript(script, ctx)
103+
return M.load(script, M.create_prescript_env(ctx))
104+
end
105+
106+
---@param script string
107+
---@param ctx Context
108+
---@return function
109+
function M.load_handler(script, ctx)
110+
return M.load(script, M.create_handler_env(ctx))
111+
end
112+
71113
return M

0 commit comments

Comments
 (0)