Skip to content

Commit e2da4dd

Browse files
author
lex
committed
feat(http): format urlencoded form body as key-value with gray values
Form-encoded request bodies (application/x-www-form-urlencoded) are now displayed as aligned key-value pairs instead of raw &-separated strings. Before: username=4666&pwd=MTIzNDU2 After: username: 4666 pwd: MTIzNDU2 - format_urlencoded_body(): parse & decode form pairs - format_verbose: urlencoded body rendered as "key: value" (verbose tab) - format_request_payload: urlencoded body rendered as "## Form Data" (Rqst tab) - apply_request_highlights: key in magenta, value in gray for Request tab - URL-decode values (%xx → char, + → space)
1 parent 37fbd1b commit e2da4dd

2 files changed

Lines changed: 96 additions & 11 deletions

File tree

lua/poste/http/format.lua

Lines changed: 89 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,55 @@ local function format_redis_body(r)
302302
return lines
303303
end
304304

305+
---------------------------------------------------------------------------
306+
-- URL-encoded form body helper
307+
---------------------------------------------------------------------------
308+
309+
--- Format urlencoded form data (application/x-www-form-urlencoded) as key-value lines.
310+
--- Returns a list of lines like " key: value".
311+
local function format_urlencoded_body(body)
312+
if not body or body == "" then return nil end
313+
local lines = {}
314+
-- Parse key=value pairs separated by &
315+
for pair in body:gmatch("[^&]+") do
316+
local key, val = pair:match("^([^=]+)=(.*)$")
317+
if key and val ~= nil then
318+
-- Decode URL-encoded values
319+
val = val:gsub("%%(%x%x)", function(h) return string.char(tonumber(h, 16)) end)
320+
val = val:gsub("+", " ")
321+
table.insert(lines, string.format(" %s: %s", key, val))
322+
end
323+
end
324+
if #lines == 0 then return nil end
325+
return lines
326+
end
327+
328+
local request_ns = vim.api.nvim_create_namespace("poste_request")
329+
330+
--- Apply highlights to the Request tab: key:value lines get key in magenta, value in gray.
331+
function M.apply_request_highlights(buf, lines)
332+
vim.api.nvim_buf_clear_namespace(buf, request_ns, 0, -1)
333+
for i, line in ipairs(lines) do
334+
local row = i - 1
335+
if line:match("^ [^:]+:%s") then
336+
local colon = line:find(":", 3)
337+
if colon then
338+
vim.api.nvim_buf_set_extmark(buf, request_ns, row, 0, {
339+
end_row = row, end_col = colon + 1,
340+
hl_group = "PosteVerboseKey", priority = 100,
341+
})
342+
local val_start = colon + 2
343+
if val_start <= #line then
344+
vim.api.nvim_buf_set_extmark(buf, request_ns, row, val_start - 1, {
345+
end_row = row, end_col = #line,
346+
hl_group = "PosteVerboseValue", priority = 100,
347+
})
348+
end
349+
end
350+
end
351+
end
352+
end
353+
305354
---------------------------------------------------------------------------
306355
-- Body view: the main response content
307356
---------------------------------------------------------------------------
@@ -619,9 +668,25 @@ function M.format_verbose(r, pending)
619668
local k, v = l:match("^([^:]+):%s*(.+)$")
620669
if k and k:lower() == "content-type" then ct = v end
621670
end
622-
local display_body = M.condense_multipart_body(request_body, ct)
623-
for l in display_body:gmatch("[^\r\n]+") do
624-
table.insert(lines, " " .. l)
671+
local ct_lower = ct:lower()
672+
if ct_lower:find("multipart/form%-data") then
673+
local display_body = M.condense_multipart_body(request_body, ct)
674+
for l in display_body:gmatch("[^\r\n]+") do
675+
table.insert(lines, " " .. l)
676+
end
677+
elseif ct_lower:find("application/x-www-form-urlencoded") then
678+
local form_lines = format_urlencoded_body(request_body)
679+
if form_lines then
680+
for _, fl in ipairs(form_lines) do
681+
table.insert(lines, fl)
682+
end
683+
else
684+
table.insert(lines, " " .. request_body)
685+
end
686+
else
687+
for l in request_body:gmatch("[^\r\n]+") do
688+
table.insert(lines, " " .. l)
689+
end
625690
end
626691
end
627692

@@ -843,14 +908,27 @@ function M.format_request_payload(r)
843908
table.insert(lines, "")
844909
end
845910
return lines
846-
end
847-
-- parsed nil → show summary line instead of raw body
848-
table.insert(lines, "(multipart form data, " .. #req_body .. " bytes)")
849-
return lines
850-
end
851-
852-
-- JSON: pretty-print
853-
if ct:find("json") or req_body:sub(1, 1) == "{" or req_body:sub(1, 1) == "[" then
911+
end
912+
-- parsed nil → show summary line instead of raw body
913+
table.insert(lines, "(multipart form data, " .. #req_body .. " bytes)")
914+
return lines
915+
end
916+
917+
-- URL-encoded form data: key-value pairs
918+
if ct:lower():find("application/x-www-form-urlencoded") then
919+
local form_lines = format_urlencoded_body(req_body)
920+
if form_lines then
921+
table.insert(lines, "## Form Data")
922+
table.insert(lines, "")
923+
for _, fl in ipairs(form_lines) do
924+
table.insert(lines, fl)
925+
end
926+
return lines
927+
end
928+
end
929+
930+
-- JSON: pretty-print
931+
if ct:find("json") or req_body:sub(1, 1) == "{" or req_body:sub(1, 1) == "[" then
854932
local ok, decoded = pcall(vim.json.decode, req_body)
855933
if ok and decoded then
856934
for l in pretty_body(req_body, "application/json"):gmatch("[^\r\n]+") do

lua/poste/http/view.lua

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ local function render_view(view, lines, filetype)
7575
end
7676
end
7777

78+
if view == "request" then
79+
local buf = buffer.get_buf()
80+
if buf then
81+
format.apply_request_highlights(buf, lines)
82+
end
83+
end
84+
7885
if view == "assertions" then
7986
local buf = buffer.get_buf()
8087
if buf then

0 commit comments

Comments
 (0)