Skip to content

Commit 98f0bfc

Browse files
fix: prevent buffer change while parsing (#535)
* fix: specify the exact buffer on `parser.parse` use Using just current buffer `0` can cause parsing on different buffer. E.g. user might open different buffer on `vim.ui.input` changing "current buffer". Specify the exact buffer instead * fix: use `nio.ui.input` instead of `vim.ui.input` * fix: wrap whole `request.run` with `nio.run`
1 parent fed46e2 commit 98f0bfc

File tree

2 files changed

+54
-76
lines changed

2 files changed

+54
-76
lines changed

lua/rest-nvim/parser/init.lua

+11-7
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ local Context = require("rest-nvim.context").Context
1313
local utils = require("rest-nvim.utils")
1414
local logger = require("rest-nvim.logger")
1515
local jar = require("rest-nvim.cookie_jar")
16+
local nio = require("nio")
1617

1718
---@alias Source integer|string Buffer or string which the `node` is extracted
1819

@@ -414,6 +415,9 @@ function parser.parse(node, source, ctx)
414415
assert(not node:has_error())
415416
local req_node = node:field("request")[1]
416417
assert(req_node)
418+
if source == 0 then
419+
source = vim.api.nvim_get_current_buf()
420+
end
417421

418422
ctx = ctx or Context:new()
419423
-- TODO: note that in-place variables won't be evaluated for raw string due to treesitter limitations
@@ -443,7 +447,7 @@ function parser.parse(node, source, ctx)
443447
url = url:gsub("\n%s+", "")
444448
elseif child_type == "pre_request_script" then
445449
parser.parse_pre_request_script(child, source, ctx)
446-
-- won't be a case anymore with latest tree-sitter-http parser. just for backward compatibility
450+
-- won't be a case anymore with latest tree-sitter-http parser. just for backward compatibility
447451
elseif child_type == "res_handler_script" then
448452
local handler = parser.parse_request_handler(child, source, ctx)
449453
if handler then
@@ -461,14 +465,14 @@ function parser.parse(node, source, ctx)
461465
if var_description == "" then
462466
var_description = nil
463467
end
464-
vim.ui.input({
468+
---@diagnostic disable-next-line: missing-fields
469+
local input = nio.ui.input({
465470
prompt = (var_description or ("Enter value for `%s`"):format(var_name)) .. ": ",
466471
default = ctx:resolve(var_name),
467-
}, function(input)
468-
if input then
469-
ctx:set_local(var_name, input)
470-
end
471-
end)
472+
})
473+
if input then
474+
ctx:set_local(var_name, input)
475+
end
472476
end
473477
elseif child_type == "variable_declaration" then
474478
parser.parse_variable_declaration(child, source, ctx)

lua/rest-nvim/request.lua

+43-69
Original file line numberDiff line numberDiff line change
@@ -60,38 +60,36 @@ local function run_request(req)
6060

6161
-- NOTE: wrap with schedule to do vim stuffs outside of lua callback loop (`on_exit`
6262
-- callback from `vim.system()` call)
63-
nio.run(function()
64-
ui.update({ request = req })
65-
local ok, res = pcall(client.request(req).wait)
66-
if not ok then
67-
logger.error("request failed")
68-
vim.notify("request failed. See `:Rest logs` for more info", vim.log.levels.ERROR, { title = "rest.nvim" })
69-
return
70-
end
71-
---@cast res rest.Response
72-
logger.info("request success")
73-
74-
-- run request handler scripts
75-
logger.debug(("run %d handers"):format(#req.handlers))
76-
vim.iter(req.handlers):each(function(f)
77-
f(res)
78-
end)
79-
logger.info("handler done")
80-
81-
_G.rest_request = req
82-
_G.rest_response = res
83-
vim.api.nvim_exec_autocmds("User", {
84-
pattern = { "RestResponse", "RestResponsePre" },
85-
})
86-
_G.rest_request = nil
87-
_G.rest_response = nil
88-
89-
-- update cookie jar
90-
jar.update_jar(req.url, res)
91-
92-
-- update result UI
93-
ui.update({ response = res })
63+
ui.update({ request = req })
64+
local ok, res = pcall(client.request(req).wait)
65+
if not ok then
66+
logger.error("request failed")
67+
vim.notify("request failed. See `:Rest logs` for more info", vim.log.levels.ERROR, { title = "rest.nvim" })
68+
return
69+
end
70+
---@cast res rest.Response
71+
logger.info("request success")
72+
73+
-- run request handler scripts
74+
logger.debug(("run %d handers"):format(#req.handlers))
75+
vim.iter(req.handlers):each(function(f)
76+
f(res)
9477
end)
78+
logger.info("handler done")
79+
80+
_G.rest_request = req
81+
_G.rest_response = res
82+
vim.api.nvim_exec_autocmds("User", {
83+
pattern = { "RestResponse", "RestResponsePre" },
84+
})
85+
_G.rest_request = nil
86+
_G.rest_response = nil
87+
88+
-- update cookie jar
89+
jar.update_jar(req.url, res)
90+
91+
-- update result UI
92+
ui.update({ response = res })
9593
-- FIXME(boltless): return future to pass the command state
9694
end
9795

@@ -107,17 +105,20 @@ function M.run(name)
107105
if config.env.enable and vim.b._rest_nvim_env_file then
108106
ctx:load_file(vim.b._rest_nvim_env_file)
109107
end
110-
local req = parser.parse(req_node, 0, ctx)
111-
if not req then
112-
logger.error("failed to parse request")
113-
vim.notify("failed to parse request", vim.log.levels.ERROR, { title = "rest.nvim" })
114-
return
115-
end
116-
local highlight = config.highlight
117-
if highlight.enable then
118-
utils.ts_highlight_node(0, req_node, require("rest-nvim.api").namespace, highlight.timeout)
119-
end
120-
run_request(req)
108+
local bufnr = vim.api.nvim_get_current_buf()
109+
nio.run(function()
110+
local req = parser.parse(req_node, bufnr, ctx)
111+
if not req then
112+
logger.error("failed to parse request")
113+
vim.notify("failed to parse request", vim.log.levels.ERROR, { title = "rest.nvim" })
114+
return
115+
end
116+
local highlight = config.highlight
117+
if highlight.enable then
118+
utils.ts_highlight_node(0, req_node, require("rest-nvim.api").namespace, highlight.timeout)
119+
end
120+
run_request(req)
121+
end)
121122
end
122123

123124
---run last request
@@ -134,31 +135,4 @@ function M.last_request()
134135
return rest_nvim_last_request
135136
end
136137

137-
-- ---run all requests in current file with same context
138-
-- function M.run_all()
139-
-- local reqs = parser.get_all_request_nodes(0)
140-
-- local ctx = Context:new()
141-
-- for _, req_node in ipairs(reqs) do
142-
-- local req = parser.parse(req_node, 0, ctx)
143-
-- if not req then
144-
-- vim.notify(
145-
-- "Parsing request failed. See `:Rest logs` for more info",
146-
-- vim.log.levels.ERROR,
147-
-- { title = "rest.nvim" }
148-
-- )
149-
-- return false
150-
-- end
151-
-- -- FIXME: wait for previous request ends
152-
-- local ok = run_request(req)
153-
-- if not ok then
154-
-- vim.notify(
155-
-- "Running request failed. See `:Rest logs` for more info",
156-
-- vim.log.levels.ERROR,
157-
-- { title = "rest.nvim" }
158-
-- )
159-
-- return
160-
-- end
161-
-- end
162-
-- end
163-
164138
return M

0 commit comments

Comments
 (0)