|
| 1 | +local logger = require("rest-nvim.logger") |
| 2 | + |
| 3 | +local function set_lines(buffer, lines) |
| 4 | + vim.api.nvim_buf_set_lines(buffer, 0, -1, false, lines) |
| 5 | +end |
| 6 | + |
| 7 | +---@param buffer integer |
| 8 | +---@param filetype string |
| 9 | +local function syntax_highlight(buffer, filetype) |
| 10 | + -- manually stop any attached tree-sitter parsers (#424, #429) |
| 11 | + vim.treesitter.stop(buffer) |
| 12 | + local lang = vim.treesitter.language.get_lang(filetype) |
| 13 | + local ok = pcall(vim.treesitter.start, buffer, lang) |
| 14 | + if not lang or not ok then |
| 15 | + vim.bo[buffer].syntax = filetype |
| 16 | + end |
| 17 | +end |
| 18 | + |
| 19 | +---@type rest.ui.panes.PaneOpts[] |
| 20 | +return { |
| 21 | + { |
| 22 | + name = "Response", |
| 23 | + render = function(self, state) |
| 24 | + if not state.request then |
| 25 | + vim.bo[self.bufnr].undolevels = -1 |
| 26 | + set_lines(self.bufnr, { "No Request running" }) |
| 27 | + return |
| 28 | + end |
| 29 | + syntax_highlight(self.bufnr, "rest_nvim_result") |
| 30 | + local lines = { |
| 31 | + "### " .. state.request.name, |
| 32 | + table.concat({ state.request.method, state.request.url, state.request.http_version }, " "), |
| 33 | + } |
| 34 | + if state.response then |
| 35 | + logger.debug(state.response.status) |
| 36 | + table.insert( |
| 37 | + lines, |
| 38 | + ("%s %d %s"):format( |
| 39 | + state.response.status.version, |
| 40 | + state.response.status.code, |
| 41 | + state.response.status.text |
| 42 | + ) |
| 43 | + ) |
| 44 | + local content_type = state.response.headers["content-type"] |
| 45 | + local body = vim.split(state.response.body, "\n") |
| 46 | + local body_meta = {} |
| 47 | + if content_type then |
| 48 | + local base_type, res_type = content_type[1]:match("(.*)/([^;]+)") |
| 49 | + -- HACK: handle application/vnd.api+json style content types |
| 50 | + res_type = res_type:match(".+%+(.*)") or res_type |
| 51 | + if base_type == "image" then |
| 52 | + body = { "Binary(image) answer" } |
| 53 | + elseif res_type == "octet_stream" then |
| 54 | + body = { "Binary answer" } |
| 55 | + -- elseif config.response.hooks.format then |
| 56 | + -- -- NOTE: format hook runs here because it should be done last. |
| 57 | + -- local ok |
| 58 | + -- body, ok = utils.gq_lines(body, res_type) |
| 59 | + -- if ok then |
| 60 | + -- table.insert(body_meta, "formatted") |
| 61 | + -- end |
| 62 | + end |
| 63 | + end |
| 64 | + local meta_str = "" |
| 65 | + if #body_meta > 0 then |
| 66 | + meta_str = " (" .. table.concat(body_meta, ",") .. ")" |
| 67 | + end |
| 68 | + table.insert(lines, "") |
| 69 | + table.insert(lines, "# @_RES" .. meta_str) |
| 70 | + vim.list_extend(lines, body) |
| 71 | + table.insert(lines, "# @_END") |
| 72 | + else |
| 73 | + vim.list_extend(lines, { "", "# Loading..." }) |
| 74 | + end |
| 75 | + set_lines(self.bufnr, lines) |
| 76 | + return false |
| 77 | + end, |
| 78 | + }, |
| 79 | + { |
| 80 | + name = "Headers", |
| 81 | + render = function(self, state) |
| 82 | + if not state.response then |
| 83 | + set_lines(self.bufnr, { "Loading..." }) |
| 84 | + return |
| 85 | + end |
| 86 | + syntax_highlight(self.bufnr, "http_stat") |
| 87 | + local lines = {} |
| 88 | + logger.debug(state.response.headers) |
| 89 | + local headers = vim.iter(state.response.headers):totable() |
| 90 | + table.sort(headers, function(b, a) |
| 91 | + return a[1] > b[1] |
| 92 | + end) |
| 93 | + logger.debug(headers) |
| 94 | + for _, header in ipairs(headers) do |
| 95 | + if header[1] ~= "set-cookie" then |
| 96 | + vim.list_extend( |
| 97 | + lines, |
| 98 | + vim.iter(header[2]) |
| 99 | + :map(function(value) |
| 100 | + return header[1] .. ": " .. value |
| 101 | + end) |
| 102 | + :totable() |
| 103 | + ) |
| 104 | + end |
| 105 | + end |
| 106 | + set_lines(self.bufnr, lines) |
| 107 | + end, |
| 108 | + }, |
| 109 | + { |
| 110 | + name = "Cookies", |
| 111 | + render = function(self, state) |
| 112 | + if not state.response then |
| 113 | + set_lines(self.bufnr, { "Loading..." }) |
| 114 | + return |
| 115 | + end |
| 116 | + local lines = {} |
| 117 | + ---@type string[]? |
| 118 | + local cookie_headers = vim.tbl_get(state.response, "headers", "set-cookie") |
| 119 | + if not cookie_headers then |
| 120 | + set_lines(self.bufnr, { "No Cookies" }) |
| 121 | + return |
| 122 | + end |
| 123 | + syntax_highlight(self.bufnr, "http_stat") |
| 124 | + table.sort(cookie_headers) |
| 125 | + vim.list_extend(lines, cookie_headers) |
| 126 | + set_lines(self.bufnr, lines) |
| 127 | + end, |
| 128 | + }, |
| 129 | + { |
| 130 | + name = "Statistics", |
| 131 | + render = function(self, state) |
| 132 | + if not state.response then |
| 133 | + set_lines(self.bufnr, { "Loading..." }) |
| 134 | + return |
| 135 | + end |
| 136 | + local lines = {} |
| 137 | + if not state.response.statistics then |
| 138 | + set_lines(self.bufnr, { "No Statistics" }) |
| 139 | + return |
| 140 | + end |
| 141 | + -- TODO: use manual highlighting instead |
| 142 | + syntax_highlight(self.bufnr, "http_stat") |
| 143 | + for _, style in ipairs(require("rest-nvim.config").clients.curl.statistics) do |
| 144 | + local title = style.title or style.id |
| 145 | + local value = state.response.statistics[style.id] or "" |
| 146 | + table.insert(lines, ("%s: %s"):format(title, value)) |
| 147 | + end |
| 148 | + set_lines(self.bufnr, lines) |
| 149 | + end, |
| 150 | + }, |
| 151 | +} |
0 commit comments