From 516f80522eb7f4d28ca1e4f3f77014c9e87fed6f Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Sun, 9 Feb 2025 15:24:16 +0000 Subject: [PATCH 1/3] refactor: wip Make whole result UI configurable. Fixes #492 --- lua/rest-nvim/config/default.lua | 5 + lua/rest-nvim/request.lua | 13 ++ .../ui/{panes.lua => panes/init.lua} | 15 +- lua/rest-nvim/ui/panes/preset/browser.lua | 112 ++++++++++ lua/rest-nvim/ui/panes/preset/legacy.lua | 151 ++++++++++++++ lua/rest-nvim/ui/panes/preset/onepage.lua | 113 +++++++++++ lua/rest-nvim/ui/result.lua | 191 +++--------------- 7 files changed, 433 insertions(+), 167 deletions(-) rename lua/rest-nvim/ui/{panes.lua => panes/init.lua} (90%) create mode 100644 lua/rest-nvim/ui/panes/preset/browser.lua create mode 100644 lua/rest-nvim/ui/panes/preset/legacy.lua create mode 100644 lua/rest-nvim/ui/panes/preset/onepage.lua diff --git a/lua/rest-nvim/config/default.lua b/lua/rest-nvim/config/default.lua index 565a8014..a17fd41e 100644 --- a/lua/rest-nvim/config/default.lua +++ b/lua/rest-nvim/config/default.lua @@ -90,6 +90,11 @@ local default_config = { ---@type string Mapping for cycle to next result pane next = "L", }, + -- TODO: add panes object as configurable pane list + -- including raw or request log + ---@type rest.ui.panes.PaneOpts[] + panes = require("rest-nvim.ui.panes.preset.browser"), + -- panes = require("rest-nvim.ui.panes.preset.onepage"), }, ---@class rest.Config.Highlight highlight = { diff --git a/lua/rest-nvim/request.lua b/lua/rest-nvim/request.lua index 01b2c6fc..0ecb0d56 100644 --- a/lua/rest-nvim/request.lua +++ b/lua/rest-nvim/request.lua @@ -84,6 +84,19 @@ local function run_request(req) }) _G.rest_request = nil _G.rest_response = nil + -- format body *after* RestResponse event + local content_type = res.headers["content-type"] + if content_type and config.response.hooks.format then + local _, res_type = content_type[#content_type]:match("(.*)/([^;]+)") + -- HACK: handle application/vnd.api+json style content types + res_type = res_type:match(".+%+(.*)") or res_type + local body, gq_ok = utils.gq_lines(vim.split(res.body, "\n"), res_type) + if not gq_ok then + res.body = "failed" + else + res.body = table.concat(body, "\n") + end + end -- update cookie jar jar.update_jar(req.url, res) diff --git a/lua/rest-nvim/ui/panes.lua b/lua/rest-nvim/ui/panes/init.lua similarity index 90% rename from lua/rest-nvim/ui/panes.lua rename to lua/rest-nvim/ui/panes/init.lua index bec593e9..791e4e89 100644 --- a/lua/rest-nvim/ui/panes.lua +++ b/lua/rest-nvim/ui/panes/init.lua @@ -4,16 +4,17 @@ ---@field name string ---@field bufnr number ---@field group rest.ui.panes.PaneGroup ----@field render fun(self:rest.ui.panes.Pane) +---@field render fun(self:rest.ui.panes.Pane, state:any) ---@class rest.ui.panes.PaneOpts ---@field name string ---@field on_init? fun(self:rest.ui.panes.Pane) ----@field render fun(self:rest.ui.panes.Pane):(modifiable:boolean?) +---@field render fun(self:rest.ui.panes.Pane, state:any):(modifiable:boolean?) ---@class rest.ui.panes.PaneGroup ---@field name string ---@field panes rest.ui.panes.Pane[] +---@field state any local RestUIPaneGroup = {} ---@param direction number function RestUIPaneGroup:cycle(direction) @@ -28,7 +29,7 @@ function RestUIPaneGroup:cycle(direction) end function RestUIPaneGroup:render() for _, pane in ipairs(self.panes) do - pane:render() + pane:render(self.state) end end ---@param winnr integer @@ -38,6 +39,10 @@ function RestUIPaneGroup:enter(winnr) end vim.api.nvim_win_set_buf(winnr, self.panes[1].bufnr) end +function RestUIPaneGroup:set_state(state) + self.state = state + self:render() +end ---@class rest.ui.panes.PaneGroupOpts ---@field on_init? fun(self:rest.ui.panes.Pane) @@ -65,7 +70,7 @@ function M.create_pane_group(name, pane_opts, opts) local pane = { name = pane_opt.name, group = group, - render = function(self) + render = function(self, state) if not self.bufnr or not vim.api.nvim_buf_is_loaded(self.bufnr) then self.bufnr = self.bufnr or vim.api.nvim_create_buf(false, false) -- small trick to ensure buffer is loaded before the `BufWinEnter` event @@ -82,7 +87,7 @@ function M.create_pane_group(name, pane_opts, opts) end end vim.bo[self.bufnr].modifiable = true - local modifiable = pane_opt.render(self) or false + local modifiable = pane_opt.render(self, state) or false if not modifiable then vim.bo[self.bufnr].undolevels = -1 else diff --git a/lua/rest-nvim/ui/panes/preset/browser.lua b/lua/rest-nvim/ui/panes/preset/browser.lua new file mode 100644 index 00000000..339868d9 --- /dev/null +++ b/lua/rest-nvim/ui/panes/preset/browser.lua @@ -0,0 +1,112 @@ +local function set_lines(buffer, lines) + vim.api.nvim_buf_set_lines(buffer, 0, -1, false, lines) +end + +---@type rest.ui.panes.PaneOpts[] +return { + { + name = "Headers", + render = function(self, state) + if not state.request then + vim.bo[self.bufnr].undolevels = -1 + set_lines(self.bufnr, { "No Request running" }) + return + end + vim.bo[self.bufnr].filetype = "rest_nvim_result" + local lines = { + "### Request: " .. state.request.name, + table.concat({ state.request.method, state.request.url, state.request.http_version }, " "), + "" + } + if not state.response then + table.insert(lines, "### Loading...") + set_lines(self.bufnr, lines) + return + end + table.insert(lines, "### Response") + table.insert( + lines, + ("%s %d %s"):format( + state.response.status.version, + state.response.status.code, + state.response.status.text + ) + ) + local headers = vim.iter(state.response.headers):totable() + table.sort(headers, function(b, a) + return a[1] > b[1] + end) + for _, header in ipairs(headers) do + vim.list_extend( + lines, + vim.iter(header[2]) + :map(function(value) + return header[1] .. ": " .. value + end) + :totable() + ) + end + set_lines(self.bufnr, lines) + end, + }, + { + name = "Payload", + render = function(self, state) + if not state.request then + set_lines(self.bufnr, { "No Request running" }) + return + end + -- TODO: render based on body types + local body = state.request.body + if vim.list_contains({ "json", "xml", "raw", "graphql" }, body.__TYPE) then + set_lines(self.bufnr, vim.split(body.data, "\n")) + if body.__TYPE == "graphql" then + vim.bo[self.bufnr].filetype = "json" + elseif body.__TYPE ~= "raw" then + vim.bo[self.bufnr].filetype = body.__TYPE + end + elseif body.__TYPE == "multiplart_form_data" then + -- TODO: + set_lines(self.bufnr, { "TODO: multipart-form-data" }) + elseif body.__TYPE == "external" then + -- TODO: + set_lines(self.bufnr, { "TODO: external body" }) + end + end, + }, + { + name = "Response", + render = function(self, state) + if not state.response then + set_lines(self.bufnr, { "Loading..." }) + return + end + ---@type string[] + local lines = {} + local content_type = state.response.headers["content-type"] + if content_type then + local base_type, res_type = content_type[#content_type]:match("(.*)/([^;]+)") + res_type = res_type:match(".+%+(.*)") or res_type + if base_type == "image" then + table.insert(lines, "Binary(image) response") + elseif res_type == "octet_stream" then + table.insert(lines, "Binary response") + else + vim.bo[self.bufnr].filetype = res_type + end + end + if #lines == 0 then + lines = vim.split(state.response.body, "\n") + end + set_lines(self.bufnr, lines) + end, + }, + { + name = "Trace", + render = function(self, _state) + -- TODO: + -- TODO: use nvim_buf_add_highlights to highlight traces + set_lines(self.bufnr, { "TODO" }) + end, + }, +} diff --git a/lua/rest-nvim/ui/panes/preset/legacy.lua b/lua/rest-nvim/ui/panes/preset/legacy.lua new file mode 100644 index 00000000..6d416d8a --- /dev/null +++ b/lua/rest-nvim/ui/panes/preset/legacy.lua @@ -0,0 +1,151 @@ +local logger = require("rest-nvim.logger") + +local function set_lines(buffer, lines) + vim.api.nvim_buf_set_lines(buffer, 0, -1, false, lines) +end + +---@param buffer integer +---@param filetype string +local function syntax_highlight(buffer, filetype) + -- manually stop any attached tree-sitter parsers (#424, #429) + vim.treesitter.stop(buffer) + local lang = vim.treesitter.language.get_lang(filetype) + local ok = pcall(vim.treesitter.start, buffer, lang) + if not lang or not ok then + vim.bo[buffer].syntax = filetype + end +end + +---@type rest.ui.panes.PaneOpts[] +return { + { + name = "Response", + render = function(self, state) + if not state.request then + vim.bo[self.bufnr].undolevels = -1 + set_lines(self.bufnr, { "No Request running" }) + return + end + syntax_highlight(self.bufnr, "rest_nvim_result") + local lines = { + "### " .. state.request.name, + table.concat({ state.request.method, state.request.url, state.request.http_version }, " "), + } + if state.response then + logger.debug(state.response.status) + table.insert( + lines, + ("%s %d %s"):format( + state.response.status.version, + state.response.status.code, + state.response.status.text + ) + ) + local content_type = state.response.headers["content-type"] + local body = vim.split(state.response.body, "\n") + local body_meta = {} + if content_type then + local base_type, res_type = content_type[1]:match("(.*)/([^;]+)") + -- HACK: handle application/vnd.api+json style content types + res_type = res_type:match(".+%+(.*)") or res_type + if base_type == "image" then + body = { "Binary(image) answer" } + elseif res_type == "octet_stream" then + body = { "Binary answer" } + -- elseif config.response.hooks.format then + -- -- NOTE: format hook runs here because it should be done last. + -- local ok + -- body, ok = utils.gq_lines(body, res_type) + -- if ok then + -- table.insert(body_meta, "formatted") + -- end + end + end + local meta_str = "" + if #body_meta > 0 then + meta_str = " (" .. table.concat(body_meta, ",") .. ")" + end + table.insert(lines, "") + table.insert(lines, "# @_RES" .. meta_str) + vim.list_extend(lines, body) + table.insert(lines, "# @_END") + else + vim.list_extend(lines, { "", "# Loading..." }) + end + set_lines(self.bufnr, lines) + return false + end, + }, + { + name = "Headers", + render = function(self, state) + if not state.response then + set_lines(self.bufnr, { "Loading..." }) + return + end + syntax_highlight(self.bufnr, "http_stat") + local lines = {} + logger.debug(state.response.headers) + local headers = vim.iter(state.response.headers):totable() + table.sort(headers, function(b, a) + return a[1] > b[1] + end) + logger.debug(headers) + for _, header in ipairs(headers) do + if header[1] ~= "set-cookie" then + vim.list_extend( + lines, + vim.iter(header[2]) + :map(function(value) + return header[1] .. ": " .. value + end) + :totable() + ) + end + end + set_lines(self.bufnr, lines) + end, + }, + { + name = "Cookies", + render = function(self, state) + if not state.response then + set_lines(self.bufnr, { "Loading..." }) + return + end + local lines = {} + ---@type string[]? + local cookie_headers = vim.tbl_get(state.response, "headers", "set-cookie") + if not cookie_headers then + set_lines(self.bufnr, { "No Cookies" }) + return + end + syntax_highlight(self.bufnr, "http_stat") + table.sort(cookie_headers) + vim.list_extend(lines, cookie_headers) + set_lines(self.bufnr, lines) + end, + }, + { + name = "Statistics", + render = function(self, state) + if not state.response then + set_lines(self.bufnr, { "Loading..." }) + return + end + local lines = {} + if not state.response.statistics then + set_lines(self.bufnr, { "No Statistics" }) + return + end + -- TODO: use manual highlighting instead + syntax_highlight(self.bufnr, "http_stat") + for _, style in ipairs(require("rest-nvim.config").clients.curl.statistics) do + local title = style.title or style.id + local value = state.response.statistics[style.id] or "" + table.insert(lines, ("%s: %s"):format(title, value)) + end + set_lines(self.bufnr, lines) + end, + }, +} diff --git a/lua/rest-nvim/ui/panes/preset/onepage.lua b/lua/rest-nvim/ui/panes/preset/onepage.lua new file mode 100644 index 00000000..4333cf59 --- /dev/null +++ b/lua/rest-nvim/ui/panes/preset/onepage.lua @@ -0,0 +1,113 @@ +local logger = require("rest-nvim.logger") + +local function set_lines(buffer, lines) + vim.api.nvim_buf_set_lines(buffer, 0, -1, false, lines) +end + +---@param buffer integer +---@param filetype string +local function syntax_highlight(buffer, filetype) + -- manually stop any attached tree-sitter parsers (#424, #429) + vim.treesitter.stop(buffer) + local lang = vim.treesitter.language.get_lang(filetype) + local ok = pcall(vim.treesitter.start, buffer, lang) + if not lang or not ok then + vim.bo[buffer].syntax = filetype + end +end + +---@type rest.ui.panes.PaneOpts[] +return { + { + name = "Response", + render = function(self, state) + if not state.request then + vim.bo[self.bufnr].undolevels = -1 + set_lines(self.bufnr, { "No Request running" }) + return + end + syntax_highlight(self.bufnr, "rest_nvim_result") + if not state.response then + set_lines(self.bufnr, { "### " .. state.request.name .. " Loading..." }) + return false + end + local lines = { "### " .. state.request.name } + logger.debug(state.response.status) + table.insert( + lines, + ("%s %d %s"):format( + state.response.status.version, + state.response.status.code, + state.response.status.text + ) + ) + local headers = vim.iter(state.response.headers):totable() + table.sort(headers, function(b, a) + return a[1] > b[1] + end) + logger.debug(headers) + for _, header in ipairs(headers) do + vim.list_extend( + lines, + vim.iter(header[2]) + :map(function(value) + return header[1] .. ": " .. value + end) + :totable() + ) + end + local content_type = state.response.headers["content-type"] + local body = vim.split(state.response.body, "\n") + local body_meta = {} + if content_type then + local base_type, res_type = content_type[1]:match("(.*)/([^;]+)") + -- HACK: handle application/vnd.api+json style content types + res_type = res_type:match(".+%+(.*)") or res_type + if base_type == "image" then + body = { "Binary(image) answer" } + elseif res_type == "octet_stream" then + body = { "Binary answer" } + -- elseif config.response.hooks.format then + -- -- NOTE: format hook runs here because it should be done last. + -- local ok + -- body, ok = utils.gq_lines(body, res_type) + -- if ok then + -- table.insert(body_meta, "formatted") + -- end + end + end + local meta_str = "" + if #body_meta > 0 then + meta_str = " (" .. table.concat(body_meta, ",") .. ")" + end + table.insert(lines, "") + table.insert(lines, "# @_RES" .. meta_str) + vim.list_extend(lines, body) + table.insert(lines, "# @_END") + set_lines(self.bufnr, lines) + return false + end, + }, + { + name = "Statistics", + render = function(self, state) + if not state.response then + set_lines(self.bufnr, { "Loading..." }) + return + end + local lines = {} + if not state.response.statistics then + set_lines(self.bufnr, { "No Statistics" }) + return + end + -- TODO: use manual highlighting instead + syntax_highlight(self.bufnr, "http_stat") + for _, style in ipairs(require("rest-nvim.config").clients.curl.statistics) do + local title = style.title or style.id + local value = state.response.statistics[style.id] or "" + table.insert(lines, ("%s: %s"):format(title, value)) + end + set_lines(self.bufnr, lines) + end, + }, +} diff --git a/lua/rest-nvim/ui/result.lua b/lua/rest-nvim/ui/result.lua index a7a2411b..96435772 100644 --- a/lua/rest-nvim/ui/result.lua +++ b/lua/rest-nvim/ui/result.lua @@ -13,22 +13,6 @@ local utils = require("rest-nvim.utils") local paneui = require("rest-nvim.ui.panes") local logger = require("rest-nvim.logger") -local function set_lines(buffer, lines) - vim.api.nvim_buf_set_lines(buffer, 0, -1, false, lines) -end - ----@param buffer integer ----@param filetype string -local function syntax_highlight(buffer, filetype) - -- manually stop any attached tree-sitter parsers (#424, #429) - vim.treesitter.stop(buffer) - local lang = vim.treesitter.language.get_lang(filetype) - local ok = lang ~= nil and pcall(vim.treesitter.start, buffer, lang) - if not lang or not ok then - vim.bo[buffer].syntax = filetype - end -end - ---data used to render the UI ---@class rest.UIData local data = { @@ -38,148 +22,30 @@ local data = { response = nil, } ----@param req rest.Request ----@return string[] -local function render_request(req) - local req_line = req.method .. " " .. req.url - if req.http_version then - req_line = req_line .. " " .. req.http_version - end - return { - "### " .. req.name, - req_line, - } -end +-- TODO: refactor UI update logic +-- - UI will have global "state" object +-- - when state object is updated, all panes will be re-rendered ----@type rest.ui.panes.PaneOpts[] -local panes = { - { - name = "Response", - render = function(self) - if not data.request then - vim.bo[self.bufnr].undolevels = -1 - set_lines(self.bufnr, { "No Request running" }) - return - end - syntax_highlight(self.bufnr, "rest_nvim_result") - local lines = render_request(data.request) - if data.response then - logger.debug(data.response.status) - table.insert( - lines, - ("%s %d %s"):format( - data.response.status.version, - data.response.status.code, - data.response.status.text - ) - ) - local content_type = data.response.headers["content-type"] - local body = vim.split(data.response.body, "\n") - local body_meta = {} - if content_type then - local base_type, res_type = content_type[1]:match("(.*)/([^;]+)") - -- HACK: handle application/vnd.api+json style content types - res_type = res_type:match(".+%+(.*)") or res_type - if base_type == "image" then - body = { "Binary(image) answer" } - elseif res_type == "octet_stream" then - body = { "Binary answer" } - elseif config.response.hooks.format then - -- NOTE: format hook runs here because it should be done last. - local ok - body, ok = utils.gq_lines(body, res_type) - if ok then - table.insert(body_meta, "formatted") - end - end - end - local meta_str = "" - if #body_meta > 0 then - meta_str = " (" .. table.concat(body_meta, ",") .. ")" - end - table.insert(lines, "") - table.insert(lines, "# @_RES" .. meta_str) - vim.list_extend(lines, body) - table.insert(lines, "# @_END") - else - vim.list_extend(lines, { "", "# Loading..." }) - end - set_lines(self.bufnr, lines) - return false - end, - }, - { - name = "Headers", - render = function(self) - if not data.response then - set_lines(self.bufnr, { "Loading..." }) - return - end - syntax_highlight(self.bufnr, "jproperties") - local lines = {} - logger.debug(data.response.headers) - local headers = vim.iter(data.response.headers):totable() - table.sort(headers, function(b, a) - return a[1] > b[1] - end) - logger.debug(headers) - for _, header in ipairs(headers) do - if header[1] ~= "set-cookie" then - vim.list_extend( - lines, - vim.iter(header[2]) - :map(function(value) - return header[1] .. ": " .. value - end) - :totable() - ) - end - end - set_lines(self.bufnr, lines) - end, - }, - { - name = "Cookies", - render = function(self) - if not data.response then - set_lines(self.bufnr, { "Loading..." }) - return - end - local lines = {} - ---@type string[]? - local cookie_headers = vim.tbl_get(data.response, "headers", "set-cookie") - if not cookie_headers then - set_lines(self.bufnr, { "No Cookies" }) - return - end - syntax_highlight(self.bufnr, "jproperties") - table.sort(cookie_headers) - vim.list_extend(lines, cookie_headers) - set_lines(self.bufnr, lines) - end, - }, - { - name = "Statistics", - render = function(self) - if not data.response then - set_lines(self.bufnr, { "Loading..." }) - return - end - local lines = {} - if not data.response.statistics then - set_lines(self.bufnr, { "No Statistics" }) - return - end - syntax_highlight(self.bufnr, "http_stat") - for _, style in ipairs(config.clients.curl.statistics) do - local title = style.title or style.id - local value = data.response.statistics[style.id] or "" - table.insert(lines, ("%s: %s"):format(title, value)) - end - set_lines(self.bufnr, lines) - end, - }, -} +-- TODO: +-- +-- Browser style: +-- Headers (request & response) <- in rest_nvim_result filetype +-- Payload (request body) <- in proper filetype +-- Response (response body) <- in proper filetype +-- Trace +-- +-- OnePage style: +-- Response (request uri & response body) <- in rest_nvim_result filetype +-- Headers (response headers) <- manual highlighting +-- Cookies (response cookies) <- manual highlighting +-- Statistics <- manual highlighting +-- +-- TODO: Request pane showing what is sent +-- TODO: change Response pane to only show the actual response (including headers if Headers +-- pane is not visible) +-- TODO: Body panes for dedicated bodies (like browser) +-- TODO: rename current Response pane to Summary pane +-- TODO: Raw pane showing raw curl log local winbar = "%#Normal# %{%v:lua.require('rest-nvim.ui.panes').winbar()%}" winbar = winbar .. "%=%<" @@ -208,7 +74,7 @@ function ui.stat_winbar() end ---@type rest.ui.panes.PaneGroup -local group = paneui.create_pane_group("rest_nvim_result", panes, { +local group = paneui.create_pane_group("rest_nvim_result", config.ui.panes, { on_init = function(self) local help = require("rest-nvim.ui.help") vim.keymap.set("n", config.ui.keybinds.prev, function() @@ -217,8 +83,9 @@ local group = paneui.create_pane_group("rest_nvim_result", panes, { vim.keymap.set("n", config.ui.keybinds.next, function() self.group:cycle(1) end, { buffer = self.bufnr }) + -- TODO(v4): change `?` mapping to `g?` vim.keymap.set("n", "?", help.open, { buffer = self.bufnr }) - vim.bo[self.bufnr].filetype = "rest_nvim_result" + vim.bo[self.bufnr].buftype = "nofile" if config.ui.winbar then utils.nvim_lazy_set_wo(self.bufnr, "winbar", winbar) end @@ -243,14 +110,14 @@ end ---Clear the UI function ui.clear() data = {} - group:render() + group:set_state(data) end ---Update data and rerender the UI ---@param new_data rest.UIData function ui.update(new_data) - data = vim.tbl_deep_extend("force", data, new_data) - group:render() + data = vim.tbl_deep_extend("force", group.state, new_data) + group:set_state(data) end return ui From 542f0386ae91c867251af464e4ade2f4b342fe88 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Thu, 6 Mar 2025 18:03:32 +0000 Subject: [PATCH 2/3] wip --- lua/rest-nvim/ui/panes/preset/browser.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lua/rest-nvim/ui/panes/preset/browser.lua b/lua/rest-nvim/ui/panes/preset/browser.lua index 339868d9..88a60013 100644 --- a/lua/rest-nvim/ui/panes/preset/browser.lua +++ b/lua/rest-nvim/ui/panes/preset/browser.lua @@ -58,6 +58,10 @@ return { end -- TODO: render based on body types local body = state.request.body + if not body then + set_lines(self.bufnr, {}) + return + end if vim.list_contains({ "json", "xml", "raw", "graphql" }, body.__TYPE) then set_lines(self.bufnr, vim.split(body.data, "\n")) if body.__TYPE == "graphql" then From aef38f989ee1481bf74665169bb57ff4c3c72cd8 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Mon, 10 Mar 2025 04:41:37 +0000 Subject: [PATCH 3/3] chore: final cleanup --- doc/rest-nvim.txt | 5 +++-- lua/rest-nvim/config/default.lua | 5 +---- lua/rest-nvim/config/init.lua | 2 ++ lua/rest-nvim/ui/result.lua | 26 -------------------------- 4 files changed, 6 insertions(+), 32 deletions(-) diff --git a/doc/rest-nvim.txt b/doc/rest-nvim.txt index bfb9acee..827c2b49 100644 --- a/doc/rest-nvim.txt +++ b/doc/rest-nvim.txt @@ -230,8 +230,9 @@ rest.Opts.Env *rest.Opts.Env* rest.Opts.UI *rest.Opts.UI* Fields: ~ - {winbar?} (boolean) Set winbar in result pane (Default: `true`) - {keybinds?} (rest.Opts.UI.Keybinds) Default mappings for result pane + {winbar?} (boolean) Set winbar in result pane (Default: `true`) + {keybinds?} (rest.Opts.UI.Keybinds) Default mappings for result pane + {panes?} (rest.ui.panes.PaneOpts[]) Result UI (Default: `rest-nvim.ui.panes.preset.legacy`) rest.Opts.UI.Keybinds *rest.Opts.UI.Keybinds* diff --git a/lua/rest-nvim/config/default.lua b/lua/rest-nvim/config/default.lua index a17fd41e..9e117f65 100644 --- a/lua/rest-nvim/config/default.lua +++ b/lua/rest-nvim/config/default.lua @@ -90,11 +90,8 @@ local default_config = { ---@type string Mapping for cycle to next result pane next = "L", }, - -- TODO: add panes object as configurable pane list - -- including raw or request log ---@type rest.ui.panes.PaneOpts[] - panes = require("rest-nvim.ui.panes.preset.browser"), - -- panes = require("rest-nvim.ui.panes.preset.onepage"), + panes = require("rest-nvim.ui.panes.preset.legacy"), }, ---@class rest.Config.Highlight highlight = { diff --git a/lua/rest-nvim/config/init.lua b/lua/rest-nvim/config/init.lua index 5b9a3eb1..e9af62b3 100644 --- a/lua/rest-nvim/config/init.lua +++ b/lua/rest-nvim/config/init.lua @@ -109,6 +109,8 @@ local config ---@field winbar? boolean --- Default mappings for result pane ---@field keybinds? rest.Opts.UI.Keybinds +--- Result UI (Default: `rest-nvim.ui.panes.preset.legacy`) +---@field panes? rest.ui.panes.PaneOpts[] ---@class rest.Opts.UI.Keybinds --- Mapping for cycle to previous result pane (Default: `"H"`) diff --git a/lua/rest-nvim/ui/result.lua b/lua/rest-nvim/ui/result.lua index 96435772..994059c5 100644 --- a/lua/rest-nvim/ui/result.lua +++ b/lua/rest-nvim/ui/result.lua @@ -11,7 +11,6 @@ local ui = {} local config = require("rest-nvim.config") local utils = require("rest-nvim.utils") local paneui = require("rest-nvim.ui.panes") -local logger = require("rest-nvim.logger") ---data used to render the UI ---@class rest.UIData @@ -22,31 +21,6 @@ local data = { response = nil, } --- TODO: refactor UI update logic --- - UI will have global "state" object --- - when state object is updated, all panes will be re-rendered - --- TODO: --- --- Browser style: --- Headers (request & response) <- in rest_nvim_result filetype --- Payload (request body) <- in proper filetype --- Response (response body) <- in proper filetype --- Trace --- --- OnePage style: --- Response (request uri & response body) <- in rest_nvim_result filetype --- Headers (response headers) <- manual highlighting --- Cookies (response cookies) <- manual highlighting --- Statistics <- manual highlighting --- --- TODO: Request pane showing what is sent --- TODO: change Response pane to only show the actual response (including headers if Headers --- pane is not visible) --- TODO: Body panes for dedicated bodies (like browser) --- TODO: rename current Response pane to Summary pane --- TODO: Raw pane showing raw curl log - local winbar = "%#Normal# %{%v:lua.require('rest-nvim.ui.panes').winbar()%}" winbar = winbar .. "%=%<" winbar = winbar .. "%{%v:lua.require('rest-nvim.ui.result').stat_winbar()%}"