Skip to content
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
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ have to leave Neovim!

- System-wide
- curl
- Optional [can be changed, see config bellow]
- Optional [can be changed, see config below]
- jq (to format JSON output)
- tidy (to format HTML output)
- Other plugins
Expand Down Expand Up @@ -83,6 +83,9 @@ use {
show_curl_command = false,
show_http_info = true,
show_headers = true,
-- table of curl `--write-out` variables or false if disabled
-- for more granular control see Statistics Spec
show_statistics = false,
-- executables or functions for formatting response body [optional]
-- set them to false if you want to disable them
formatters = {
Expand Down Expand Up @@ -154,6 +157,14 @@ To run `rest.nvim` you should map the following commands:
- `custom_dynamic_variables` allows to extend or overwrite built-in dynamic variable functions
(default: {})

### Statistics Spec

| Property | Type | Description |
| :------- | :----------------- | :----------------------------------------------------- |
| [1] | string | `--write-out` variable name, see `man curl`. Required. |
| title | string | Replaces the variable name in the output if defined. |
| type | string or function | Specifies type transformation for the output value. Default transformers are `time` and `size`. Can also be a function which takes the value as a parameter and returns a string. |

## Usage

Create a new http file or open an existing one and place the cursor over the
Expand Down
1 change: 1 addition & 0 deletions lua/rest-nvim/config/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ local config = {
show_url = true,
show_http_info = true,
show_headers = true,
show_statistics = false,
formatters = {
json = "jq",
html = function(body)
Expand Down
9 changes: 9 additions & 0 deletions lua/rest-nvim/curl/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,15 @@ local function create_callback(curl_cmd, opts)
end
end

if config.get("result").show_statistics then
-- Statistics, e.g. Total Time: 123.4 ms
local statistics

res.body, statistics = utils.parse_statistics(res.body)

utils.write_block(res_bufnr, statistics, true)
end

--- Add the curl command results into the created buffer
local formatter = config.get("result").formatters[content_type]
-- format response body
Expand Down
17 changes: 17 additions & 0 deletions lua/rest-nvim/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,23 @@ rest.run_request = function(req, opts)
spliced_body = splice_body(result.headers, result.body)
end

if config.get("result").show_statistics then
local statistics_line = {}

for _, tbl in ipairs(config.get("result").show_statistics) do
if type(tbl) == "string" then
tbl = { tbl }
end

table.insert(statistics_line, tbl[1] .. "=%{" .. tbl[1] .. "}")
end

curl_raw_args = vim.tbl_extend("force", curl_raw_args, {
"--write-out",
"\\n" .. table.concat(statistics_line, "&"),
})
end

Opts = {
request_id = vim.loop.now(), -- request id used to correlate RestStartRequest and RestStopRequest events
method = result.method:lower(),
Expand Down
106 changes: 106 additions & 0 deletions lua/rest-nvim/utils/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,112 @@ M.split_list = function(tbl, index, inclusive)
return out
end

--- Default transformers for statistics
local transform = {
time = function(time)
time = tonumber(time)

if time >= 60 then
time = string.format("%.2f", time / 60)

return time .. " min"
end

local units = { "s", "ms", "µs", "ns" }
local unit = 1

while time < 1 and unit <= #units do
time = time * 1000
unit = unit + 1
end

time = string.format("%.2f", time)

return time .. " " .. units[unit]
end,

size = function(bytes)
bytes = tonumber(bytes)

local units = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" }
local unit = 1

while bytes >= 1024 and unit <= #units do
bytes = bytes / 1024
unit = unit + 1
end

bytes = string.format("%.2f", bytes)

return bytes .. " " .. units[unit]
end,
}

--- Parse statistics line to a table with key, value pairs
---
--- @param statistics_line string The statistics line from body
---
--- @return string[] statistics
local get_parsed_statistics = function(statistics_line)
local out = {}

for _, statistics_pair in ipairs(M.split(statistics_line, "&")) do
local value = M.split(statistics_pair, "=", 1)

if #value == 1 then
table.insert(out, value[1])
else
out[value[1]] = value[2]
end
end

return out
end

--- Parse and transform statistics line to a table of strings to be output.
--- Returns the body without statistics line and a table of statistics lines.
---
--- @param body string Response body
---
--- @return string body, string[] statistics
M.parse_statistics = function(body)
local _, _, statistics = string.find(body, "[%c%s]+([^%c]*)$")
local config_statistics = config.get("result").show_statistics

body = string.gsub(body, "[%c%s]+([^%c]*)$", "")
local out = {}

statistics = get_parsed_statistics(statistics)

for _, tbl in ipairs(config_statistics) do
if type(tbl) == "string" then
tbl = { tbl }
end

local value = statistics[tbl[1]]

if tbl.type then
if type(tbl.type) == "string" then
value = transform[tbl.type](value)
end

if type(tbl.type) == "function" then
value = tbl.type(value)
end
else
for key, fun in pairs(transform) do
if string.match(tbl[1], "^" .. key) then
value = fun(value)
end
end
end

table.insert(out, (tbl.title or (tbl[1] .. " ")) .. value)
end

return body, out
end

-- http_status returns the status code and the meaning, e.g. 200 OK
-- see https://httpstatuses.com/ for reference
-- @param code The request status code
Expand Down