Skip to content

Commit 5fa9afc

Browse files
ref!(ui): rewrite result pane UI
1 parent ce55212 commit 5fa9afc

File tree

11 files changed

+419
-79
lines changed

11 files changed

+419
-79
lines changed

lua/rest-nvim/autocmds.lua

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,51 +8,9 @@
88

99
local autocmds = {}
1010

11-
local result = require("rest-nvim.result")
12-
local config = require("rest-nvim.config")
13-
local result_help = require("rest-nvim.result.help")
14-
1511
---Set up Rest autocommands group
1612
function autocmds.setup()
17-
local rest_nvim_augroup = vim.api.nvim_create_augroup("Rest", {})
18-
local keybinds = config.result.keybinds
19-
20-
vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, {
21-
group = rest_nvim_augroup,
22-
pattern = "rest_nvim_results",
23-
callback = function(args)
24-
vim.keymap.set("n", keybinds.prev, function()
25-
result.cycle_pane(-1)
26-
end, {
27-
desc = "Go to previous winbar pane",
28-
buffer = args.buf,
29-
})
30-
vim.keymap.set("n", keybinds.next, function()
31-
result.cycle_pane(1)
32-
end, {
33-
desc = "Go to next winbar pane",
34-
buffer = args.buf,
35-
})
36-
vim.keymap.set("n", "?", result_help.open, {
37-
desc = "Open rest.nvim request results help window",
38-
buffer = args.buf,
39-
})
40-
vim.keymap.set("n", "q", function()
41-
vim.api.nvim_buf_delete(args.buf, { unload = true })
42-
end, { desc = "Close rest.nvim results buffer", buffer = args.buf })
43-
end,
44-
desc = "Set up rest.nvim results buffer keybinds",
45-
})
46-
vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, {
47-
group = rest_nvim_augroup,
48-
pattern = "rest_winbar_help",
49-
callback = function(args)
50-
vim.keymap.set("n", "q", result_help.close, {
51-
desc = "Close rest.nvim request results help window",
52-
buffer = args.buf,
53-
})
54-
end,
55-
})
13+
vim.api.nvim_create_augroup("Rest", { clear = true })
5614
end
5715

5816
---Register a new autocommand in the `Rest` augroup
@@ -71,7 +29,7 @@ function autocmds.register_autocmd(events, cb, description)
7129
})
7230

7331
local autocmd_opts = {
74-
group = "Rest",
32+
group = vim.api.nvim_create_augroup("Rest", { clear = false }),
7533
pattern = "*.http",
7634
desc = description,
7735
}

lua/rest-nvim/config/init.lua

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ local default_config = {
8989
horizontal = false,
9090
---@type boolean Change the focus to the results window or stay in the current window (HTTP file)
9191
enter = false,
92+
---@type boolean
93+
headers = true,
94+
---@type boolean
95+
cookies = true,
9296
},
9397
---@class RestConfigResultBehavior
9498
behavior = {
@@ -102,8 +106,8 @@ local default_config = {
102106
---@see https://curl.se/libcurl/c/curl_easy_getinfo.html
103107
---@type table<string,RestOptsResultStatStyle>
104108
stats = {
105-
total_time = { winbar = true, title = "Time taken" },
106-
size_download_t = { winbar = true, title = "Download size" },
109+
total_time = { winbar = "take", title = "Time taken" },
110+
size_download_t = { winbar = "size", title = "Download size" },
107111
},
108112
},
109113
---@type table<string,RestResultFormatters>

lua/rest-nvim/parser/init.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,12 @@ function M.parse(node, source, context)
254254
M.parse_pre_request_script(script_node, source, context)
255255
end
256256
local handler_nodes = collect_next_siblings(req_node, {"res_handler_script"})
257-
local handlers = vim.iter(handler_nodes):map(function (node)
258-
return M.parse_request_handler(node, source, context)
257+
local handlers = vim.iter(handler_nodes):map(function (n)
258+
return M.parse_request_handler(n, source, context)
259259
end):totable()
260260
local headers = parse_headers(req_node, source, context)
261-
if headers["host"] then
261+
-- HACK: check if url doesn't have host
262+
if headers["host"] and url[1] == "/" then
262263
url = headers["host"]..url
263264
headers["host"] = nil
264265
end

lua/rest-nvim/request.lua

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ local parser = require("rest-nvim.parser")
66
local utils = require("rest-nvim.utils")
77
local logger = require("rest-nvim.logger")
88
local config = require("rest-nvim.config")
9+
local ui = require("rest-nvim.ui.result")
10+
local nio = require("nio")
911

1012
---@class Request
1113
---@field context Context
@@ -24,26 +26,41 @@ local rest_nvim_last_request = nil
2426
---@return boolean ok
2527
local function run_request(req)
2628
logger.debug("run_request")
27-
local client = require("rest-nvim.client.curl")
29+
local client = require("rest-nvim.client.curl.cli")
2830
rest_nvim_last_request = req
2931

30-
logger.info("sending request to: " .. req.url)
31-
local res = client.request_(req)
32-
if not res then
33-
logger.error("request failed")
34-
return false
35-
end
36-
logger.debug("request success")
32+
-- remove previous result
33+
_G._rest_nvim_result = nil
34+
-- clear the ui
35+
ui.update()
36+
37+
-- open result UI
38+
ui.open_ui()
39+
40+
-- TODO: set UI with request informations (e.g. method & get)
41+
42+
nio.run(function ()
43+
local ok, res = pcall(client.request(req).wait)
44+
if not ok then
45+
logger.error("request failed")
46+
-- TODO: should return here
47+
return
48+
end
49+
logger.info("request success")
50+
-- wrap with schedule to set global variable outside of lua callback loop
51+
vim.schedule(function ()
52+
_G._rest_nvim_result = res
3753

38-
-- run request handler scripts
39-
vim.iter(req.handlers):each(function (f) f() end)
54+
-- run request handler scripts
55+
vim.iter(req.handlers):each(function (f) f() end)
4056

41-
logger.debug("handler end")
57+
logger.info("handler done")
4258

43-
-- update result UI
44-
local result = require("rest-nvim.result")
45-
local result_buf = result.get_or_create_buf()
46-
result.write_res(result_buf, res)
59+
-- update result UI
60+
ui.update()
61+
end)
62+
end)
63+
-- FIXME: use future instead of returning true here
4764
return true
4865
end
4966

@@ -91,12 +108,12 @@ function M.run_all()
91108
for _, req_node in ipairs(reqs) do
92109
local req = parser.parse(req_node, 0, ctx)
93110
if not req then
94-
vim.notify("Parsing request failed. See `:Rest log` for more info", vim.log.levels.ERROR)
111+
vim.notify("Parsing request failed. See `:Rest logs` for more info", vim.log.levels.ERROR)
95112
return false
96113
end
97114
local ok = run_request(req)
98115
if not ok then
99-
vim.notify("Running request failed. See `:Rest log` for more info", vim.log.levels.ERROR)
116+
vim.notify("Running request failed. See `:Rest logs` for more info", vim.log.levels.ERROR)
100117
return false
101118
end
102119
end

lua/rest-nvim/result/init.lua

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,10 @@ local function format_body(bufnr, headers, res)
228228
if vim.v.shell_error == 0 then
229229
res.body = stdout
230230
else
231-
---@diagnostic disable-next-line need-check-nil
232231
logger.error("Error running formatter '" .. fmt .. "' on response body:\n" .. stdout)
233232
end
234233
end
235234
elseif res_type ~= nil then
236-
---@diagnostic disable-next-line need-check-nil
237235
logger.info(
238236
"Could not find a formatter for the body type "
239237
.. res_type
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
---@mod rest-nvim.result.help rest.nvim result buffer help
1+
---@mod rest-nvim.ui.help rest.nvim result buffer help
22
---
33
---@brief [[
44
---
@@ -32,6 +32,10 @@ local function get_or_create_buf()
3232
vim.api.nvim_buf_set_name(new_bufnr, tmp_name)
3333
vim.api.nvim_set_option_value("ft", "markdown", { buf = new_bufnr })
3434
vim.api.nvim_set_option_value("buftype", "nofile", { buf = new_bufnr })
35+
vim.keymap.set("n", "q", help.close, {
36+
desc = "Close rest.nvim request results help window",
37+
buffer = new_bufnr,
38+
})
3539

3640
-- Write to buffer
3741
local buf_content = {
@@ -57,12 +61,7 @@ function help.open()
5761
local help_bufnr = get_or_create_buf()
5862

5963
-- Get the results buffer window ID
60-
local winnr
61-
for _, id in ipairs(vim.api.nvim_list_wins()) do
62-
if vim.api.nvim_buf_get_name(vim.api.nvim_win_get_buf(id)):find("rest_nvim_results") then
63-
winnr = id
64-
end
65-
end
64+
local winnr = vim.api.nvim_get_current_win()
6665

6766
-- Help window sizing and positioning
6867
local width = math.floor(vim.api.nvim_win_get_width(winnr) / 2)

lua/rest-nvim/ui/panes.lua

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
---@mod rest-nvim.ui.panes Small internal library to create pane style window
2+
3+
---@class RestUIPane
4+
---@field name string
5+
---@field bufnr number
6+
---@field group RestUIPaneGroup
7+
---@field render fun(self:RestUIPane)
8+
9+
---@class RestUIPaneOpts
10+
---@field name string
11+
---@field on_init? fun(self:RestUIPane)
12+
---@field render fun(self:RestUIPane):(modifiable:boolean?)
13+
14+
---@class RestUIPaneGroup
15+
---@field name string
16+
---@field panes RestUIPane[]
17+
local RestUIPaneGroup = {}
18+
---@param direction number
19+
function RestUIPaneGroup:cycle(direction)
20+
for index, pane in ipairs(self.panes) do
21+
if pane.bufnr == vim.api.nvim_get_current_buf() then
22+
local next_index = (index + direction - 1) % #self.panes + 1
23+
vim.api.nvim_win_set_buf(0, self.panes[next_index].bufnr)
24+
return
25+
end
26+
end
27+
vim.notify("`cycle()` can only be called inside the pane buffer", vim.log.levels.WARN)
28+
end
29+
function RestUIPaneGroup:render()
30+
for _, pane in ipairs(self.panes) do
31+
pane:render()
32+
end
33+
end
34+
function RestUIPaneGroup:enter(winnr)
35+
if not self.panes[1].bufnr then
36+
self:render()
37+
end
38+
vim.api.nvim_win_set_buf(winnr, self.panes[1].bufnr)
39+
end
40+
41+
---@class RestUIPaneGroupOpts
42+
---@field on_init? fun(self:RestUIPane)
43+
44+
local M = {}
45+
46+
---@type table<string,RestUIPaneGroup>
47+
local groups = {}
48+
49+
---@param name string
50+
---@param pane_opts RestUIPaneOpts[]
51+
---@param opts? RestUIPaneGroupOpts
52+
---@return RestUIPaneGroup
53+
function M.create_pane_group(name, pane_opts, opts)
54+
---@type RestUIPaneGroup
55+
local group = { name = name, panes = {} }
56+
setmetatable(group, { __index = RestUIPaneGroup })
57+
-- TODO: validate name doesn't conflict
58+
groups[name] = group
59+
for _, pane_opt in ipairs(pane_opts) do
60+
---@type RestUIPane
61+
---@diagnostic disable-next-line: missing-fields
62+
local pane = {
63+
name = pane_opt.name,
64+
group = group,
65+
render = function (self)
66+
if not self.bufnr then
67+
self.bufnr = vim.api.nvim_create_buf(false, false)
68+
vim.bo[self.bufnr].modifiable = false
69+
vim.bo[self.bufnr].swapfile = false
70+
vim.bo[self.bufnr].buftype = "nofile"
71+
vim.b[self.bufnr].__pane_group = name
72+
-- HACK: I can't set buffer name because it will allow `:edit` command
73+
-- vim.api.nvim_buf_set_name(self.bufnr, name .. "#" .. self.name)
74+
if opts and opts.on_init then
75+
opts.on_init(self)
76+
end
77+
if pane_opt.on_init then
78+
pane_opt.on_init(self)
79+
end
80+
end
81+
vim.bo[self.bufnr].modifiable = true
82+
local modifiable = pane_opt.render(self) or false
83+
if not modifiable then
84+
vim.bo[self.bufnr].undolevels = -1
85+
end
86+
vim.bo[self.bufnr].modifiable = modifiable
87+
end
88+
}
89+
table.insert(group.panes, pane)
90+
end
91+
return group
92+
end
93+
94+
---@return string
95+
function M.winbar()
96+
local group = groups[vim.b.__pane_group]
97+
if not group then
98+
return "not a pane buffer"
99+
end
100+
local winbar = {}
101+
for _, pane in ipairs(group.panes) do
102+
if pane.bufnr == vim.api.nvim_get_current_buf() then
103+
table.insert(winbar, "%#RestPaneTitle#" .. pane.name .. "%#Normal#")
104+
else
105+
table.insert(winbar, "%#RestPaneTitleNC#" .. pane.name .. "%#Normal#")
106+
end
107+
end
108+
return table.concat(winbar, " %#RestText#|%#Normal# ")
109+
end
110+
111+
return M

0 commit comments

Comments
 (0)