Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: prevent buffer change while parsing #535

Merged
merged 5 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lua/rest-nvim/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
---
---@brief ]]

---@toc rocks-contents
---@toc rest-contents

local rest = {}

Expand Down
18 changes: 11 additions & 7 deletions lua/rest-nvim/parser/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ local Context = require("rest-nvim.context").Context
local utils = require("rest-nvim.utils")
local logger = require("rest-nvim.logger")
local jar = require("rest-nvim.cookie_jar")
local nio = require("nio")

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

Expand Down Expand Up @@ -414,6 +415,9 @@ function parser.parse(node, source, ctx)
assert(not node:has_error())
local req_node = node:field("request")[1]
assert(req_node)
if source == 0 then
source = vim.api.nvim_get_current_buf()
end

ctx = ctx or Context:new()
-- TODO: note that in-place variables won't be evaluated for raw string due to treesitter limitations
Expand Down Expand Up @@ -443,7 +447,7 @@ function parser.parse(node, source, ctx)
url = url:gsub("\n%s+", "")
elseif child_type == "pre_request_script" then
parser.parse_pre_request_script(child, source, ctx)
-- won't be a case anymore with latest tree-sitter-http parser. just for backward compatibility
-- won't be a case anymore with latest tree-sitter-http parser. just for backward compatibility
elseif child_type == "res_handler_script" then
local handler = parser.parse_request_handler(child, source, ctx)
if handler then
Expand All @@ -461,14 +465,14 @@ function parser.parse(node, source, ctx)
if var_description == "" then
var_description = nil
end
vim.ui.input({
---@diagnostic disable-next-line: missing-fields
local input = nio.ui.input({
prompt = (var_description or ("Enter value for `%s`"):format(var_name)) .. ": ",
default = ctx:resolve(var_name),
}, function(input)
if input then
ctx:set_local(var_name, input)
end
end)
})
if input then
ctx:set_local(var_name, input)
end
end
elseif child_type == "variable_declaration" then
parser.parse_variable_declaration(child, source, ctx)
Expand Down
112 changes: 43 additions & 69 deletions lua/rest-nvim/request.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,38 +60,36 @@ local function run_request(req)

-- NOTE: wrap with schedule to do vim stuffs outside of lua callback loop (`on_exit`
-- callback from `vim.system()` call)
nio.run(function()
ui.update({ request = req })
local ok, res = pcall(client.request(req).wait)
if not ok then
logger.error("request failed")
vim.notify("request failed. See `:Rest logs` for more info", vim.log.levels.ERROR, { title = "rest.nvim" })
return
end
---@cast res rest.Response
logger.info("request success")

-- run request handler scripts
logger.debug(("run %d handers"):format(#req.handlers))
vim.iter(req.handlers):each(function(f)
f(res)
end)
logger.info("handler done")

_G.rest_request = req
_G.rest_response = res
vim.api.nvim_exec_autocmds("User", {
pattern = { "RestResponse", "RestResponsePre" },
})
_G.rest_request = nil
_G.rest_response = nil

-- update cookie jar
jar.update_jar(req.url, res)

-- update result UI
ui.update({ response = res })
ui.update({ request = req })
local ok, res = pcall(client.request(req).wait)
if not ok then
logger.error("request failed")
vim.notify("request failed. See `:Rest logs` for more info", vim.log.levels.ERROR, { title = "rest.nvim" })
return
end
---@cast res rest.Response
logger.info("request success")

-- run request handler scripts
logger.debug(("run %d handers"):format(#req.handlers))
vim.iter(req.handlers):each(function(f)
f(res)
end)
logger.info("handler done")

_G.rest_request = req
_G.rest_response = res
vim.api.nvim_exec_autocmds("User", {
pattern = { "RestResponse", "RestResponsePre" },
})
_G.rest_request = nil
_G.rest_response = nil

-- update cookie jar
jar.update_jar(req.url, res)

-- update result UI
ui.update({ response = res })
-- FIXME(boltless): return future to pass the command state
end

Expand All @@ -107,17 +105,20 @@ function M.run(name)
if config.env.enable and vim.b._rest_nvim_env_file then
ctx:load_file(vim.b._rest_nvim_env_file)
end
local req = parser.parse(req_node, 0, ctx)
if not req then
logger.error("failed to parse request")
vim.notify("failed to parse request", vim.log.levels.ERROR, { title = "rest.nvim" })
return
end
local highlight = config.highlight
if highlight.enable then
utils.ts_highlight_node(0, req_node, require("rest-nvim.api").namespace, highlight.timeout)
end
run_request(req)
local bufnr = vim.api.nvim_get_current_buf()
nio.run(function()
local req = parser.parse(req_node, bufnr, ctx)
if not req then
logger.error("failed to parse request")
vim.notify("failed to parse request", vim.log.levels.ERROR, { title = "rest.nvim" })
return
end
local highlight = config.highlight
if highlight.enable then
utils.ts_highlight_node(0, req_node, require("rest-nvim.api").namespace, highlight.timeout)
end
run_request(req)
end)
end

---run last request
Expand All @@ -134,31 +135,4 @@ function M.last_request()
return rest_nvim_last_request
end

-- ---run all requests in current file with same context
-- function M.run_all()
-- local reqs = parser.get_all_request_nodes(0)
-- local ctx = Context:new()
-- for _, req_node in ipairs(reqs) do
-- local req = parser.parse(req_node, 0, ctx)
-- if not req then
-- vim.notify(
-- "Parsing request failed. See `:Rest logs` for more info",
-- vim.log.levels.ERROR,
-- { title = "rest.nvim" }
-- )
-- return false
-- end
-- -- FIXME: wait for previous request ends
-- local ok = run_request(req)
-- if not ok then
-- vim.notify(
-- "Running request failed. See `:Rest logs` for more info",
-- vim.log.levels.ERROR,
-- { title = "rest.nvim" }
-- )
-- return
-- end
-- end
-- end

return M