Skip to content

Commit

Permalink
feat: refactor writing to buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
Rasmus-Bertell committed Nov 21, 2023
1 parent c186d3e commit e326b56
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 63 deletions.
77 changes: 39 additions & 38 deletions lua/rest-nvim/curl/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,14 @@ M.get_or_create_buf = function()
local existing_bufnr = vim.fn.bufnr(tmp_name)
if existing_bufnr ~= -1 then
-- Set modifiable
vim.api.nvim_set_option_value("modifiable", true, { buf = existing_bufnr})
vim.api.nvim_set_option_value("modifiable", true, { buf = existing_bufnr })
-- Prevent modified flag
vim.api.nvim_set_option_value("buftype", "nofile", { buf = existing_bufnr})
vim.api.nvim_set_option_value("buftype", "nofile", { buf = existing_bufnr })
-- Delete buffer content
vim.api.nvim_buf_set_lines(
existing_bufnr,
0,
vim.api.nvim_buf_line_count(existing_bufnr) - 1,
false,
{}
)
vim.api.nvim_buf_set_lines(existing_bufnr, 0, -1, false, {})

-- Make sure the filetype of the buffer is httpResult so it will be highlighted
vim.api.nvim_set_option_value("ft", "httpResult", { buf = existing_bufnr } )
vim.api.nvim_set_option_value("ft", "httpResult", { buf = existing_bufnr })

return existing_bufnr
end
Expand All @@ -116,9 +110,29 @@ local function create_callback(curl_cmd, opts)
return
end
local res_bufnr = M.get_or_create_buf()
local header_lines = res.headers

local headers = utils.filter(res.headers, function(value)
return value ~= ""
end, false)

headers = utils.map(headers, function(value)
local _, _, http, status = string.find(value, "^(HTTP.*)%s+(%d+)%s*$")
vim.print(value, http, status)

if http and status then
return http .. " " .. utils.http_status(tonumber(status))
end

return value
end)

headers = utils.split_list(headers, function(value)
return string.find(value, "^HTTP.*$")
end)

res.headers = parse_headers(res.headers)
local content_type = res.headers[utils.key(res.headers,'content-type')]

local content_type = utils.get_value(res.headers, "content-type")
if content_type then
content_type = content_type:match("application/([-a-z]+)") or content_type:match("text/(%l+)")
end
Expand All @@ -139,45 +153,32 @@ local function create_callback(curl_cmd, opts)
end
end

-- This can be quite verbose so let user control it
if config.get("result").show_curl_command then
vim.api.nvim_buf_set_lines(res_bufnr, 0, 0, false, { "Command: " .. curl_cmd })
end

if config.get("result").show_url then
--- Add metadata into the created buffer (status code, date, etc)
-- Request statement (METHOD URL)
vim.api.nvim_buf_set_lines(res_bufnr, 0, 0, false, { method:upper() .. " " .. url })
utils.write_block(res_bufnr, { method:upper() .. " " .. url }, false)
end

-- This can be quite verbose so let user control it
if config.get("result").show_curl_command then
utils.write_block(res_bufnr, { "Command: " .. curl_cmd }, true)
end

if config.get("result").show_http_info then
local line_count = vim.api.nvim_buf_line_count(res_bufnr)
local separator = config.get("result").show_url and 0 or 1
-- HTTP version, status code and its meaning, e.g. HTTP/1.1 200 OK
vim.api.nvim_buf_set_lines(
res_bufnr,
line_count - separator,
line_count - separator,
false,
{ "HTTP/1.1 " .. utils.http_status(res.status) }
)
utils.write_block(res_bufnr, { "HTTP/1.1 " .. utils.http_status(res.status) }, false)
end

if config.get("result").show_headers then
local line_count = vim.api.nvim_buf_line_count(res_bufnr)
-- Headers, e.g. Content-Type: application/json
vim.api.nvim_buf_set_lines(
res_bufnr,
line_count + 1,
line_count + 1 + #header_lines,
false,
header_lines
)
for _, header_block in ipairs(headers) do
utils.write_block(res_bufnr, header_block, true)
end
end

--- Add the curl command results into the created buffer
local formatter = config.get("result").formatters[content_type]
-- formate response body
-- format response body
if type(formatter) == "function" then
local ok, out = pcall(formatter, res.body)
-- check if formatter ran successfully
Expand Down Expand Up @@ -220,8 +221,8 @@ local function create_callback(curl_cmd, opts)
buf_content = buf_content .. "\n#+END"

local lines = utils.split(buf_content, "\n")
local line_count = vim.api.nvim_buf_line_count(res_bufnr) - 1
vim.api.nvim_buf_set_lines(res_bufnr, line_count, line_count + #lines, false, lines)

utils.write_block(res_bufnr, lines)

-- Only open a new split if the buffer is not loaded into the current window
if vim.fn.bufwinnr(res_bufnr) == -1 then
Expand Down
12 changes: 7 additions & 5 deletions lua/rest-nvim/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ local function load_external_payload(fileimport_string)
end
end


-- @param headers table HTTP headers
-- @param payload table of the form { external = bool, filename_tpl= path, body_tpl = string }
-- with body_tpl an array of lines
Expand All @@ -101,7 +100,7 @@ local function splice_body(headers, payload)
else
lines = payload.body_tpl
end
local content_type = headers[utils.key(headers,"content-type")] or ""
local content_type = utils.get_value(headers, "content-type") or ""
local has_json = content_type:find("application/[^ ]*json")

local body = ""
Expand Down Expand Up @@ -140,8 +139,9 @@ end
rest.run_request = function(req, opts)
-- TODO rename result to request
local result = req
local curl_raw_args = config.get("skip_ssl_verification") and vim.list_extend(result.raw, { "-k" })
or result.raw
local curl_raw_args = config.get("skip_ssl_verification")
and vim.list_extend(result.raw, { "-k" })
or result.raw
opts = vim.tbl_deep_extend(
"force", -- use value from rightmost map
defaultRequestOpts,
Expand All @@ -153,7 +153,9 @@ rest.run_request = function(req, opts)
local spliced_body = nil
if not req.body.inline and req.body.filename_tpl then
curl_raw_args = vim.tbl_extend("force", curl_raw_args, {
'--data-binary', '@'..load_external_payload(req.body.filename_tpl)})
"--data-binary",
"@" .. load_external_payload(req.body.filename_tpl),
})
else
spliced_body = splice_body(result.headers, result.body)
end
Expand Down
38 changes: 19 additions & 19 deletions lua/rest-nvim/request/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ local function get_importfile_name(bufnr, start_line, stop_line)
local fileimport_inlined
fileimport_line = vim.api.nvim_buf_get_lines(bufnr, import_line - 1, import_line, false)
-- check second char against '@' (meaning "dont inline")
fileimport_inlined = string.sub(fileimport_line[1], 2, 2) ~= '@'
fileimport_string = string.gsub(fileimport_line[1], "<@?", "", 1):gsub("^%s+", ""):gsub("%s+$", "")
fileimport_inlined = string.sub(fileimport_line[1], 2, 2) ~= "@"
fileimport_string =
string.gsub(fileimport_line[1], "<@?", "", 1):gsub("^%s+", ""):gsub("%s+$", "")
return fileimport_inlined, fileimport_string

end
return nil
end
Expand All @@ -42,7 +42,7 @@ local function get_body(bufnr, start_line, stop_line)
local inline, importfile = get_importfile_name(bufnr, start_line, stop_line)
local lines -- an array of strings
if importfile ~= nil then
return { external = true; inline = inline; filename_tpl = importfile }
return { external = true, inline = inline, filename_tpl = importfile }
else
lines = vim.api.nvim_buf_get_lines(bufnr, start_line, stop_line, false)
end
Expand All @@ -63,7 +63,7 @@ local function get_body(bufnr, start_line, stop_line)
end
end

return { external = false; inline = false; body_tpl = lines2 }
return { external = false, inline = false, body_tpl = lines2 }
end

local function get_response_script(bufnr, start_line, stop_line)
Expand Down Expand Up @@ -285,9 +285,9 @@ M.buf_get_request = function(bufnr, curpos)

local curl_args, body_start = get_curl_args(bufnr, headers_end, end_line)

local host = headers[utils.key(headers,"host")] or ""
local host = utils.get_value(headers, "host") or ""
parsed_url.url = host:gsub("%s+", "") .. parsed_url.url
headers[utils.key(headers,"host")] = nil
headers[utils.key(headers, "host")] = nil

local body = get_body(bufnr, body_start, end_line)

Expand All @@ -302,17 +302,17 @@ M.buf_get_request = function(bufnr, curpos)
end

local req = {
method = parsed_url.method,
url = parsed_url.url,
http_version = parsed_url.http_version,
headers = headers,
raw = curl_args,
body = body,
bufnr = bufnr,
start_line = start_line,
end_line = end_line,
script_str = script_str,
}
method = parsed_url.method,
url = parsed_url.url,
http_version = parsed_url.http_version,
headers = headers,
raw = curl_args,
body = body,
bufnr = bufnr,
start_line = start_line,
end_line = end_line,
script_str = script_str,
}

return true, req
end
Expand Down Expand Up @@ -393,7 +393,7 @@ M.highlight = function(bufnr, start_line, end_line)
higroup,
{ start_line - 1, 0 },
{ end_line - 1, end_column },
{ regtype = "c"; inclusive = false }
{ regtype = "c", inclusive = false }
)

vim.defer_fn(function()
Expand Down
103 changes: 102 additions & 1 deletion lua/rest-nvim/utils/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ M.get_variables = function()
if variables[name]:match(oname) then
-- Add that into the variable
-- I.E if @url={{path}}:{{port}}/{{source}}
-- Substitue in path, port and source
-- Substitute in path, port and source
variables[name] = variables[name]:gsub("{{" .. oname .. "}}", ovalue)
end
end
Expand Down Expand Up @@ -317,6 +317,16 @@ M.key = function(tbl, key)
return key
end

--- Get the table value or nil if not found
---
--- @param tbl (table) Table to iterate over
--- @param key (string) The key to the value case insensitive
---
--- @return any
M.get_value = function(tbl, key)
return tbl[M.key(tbl, key)]
end

-- tbl_to_str recursively converts the provided table into a json string
-- @param tbl Table to convert into a String
-- @param json If the string should use a key:value syntax
Expand Down Expand Up @@ -417,6 +427,97 @@ M.contains_comments = function(str)
return str:find("^#") or str:find("^%s+#")
end

--- Filter a table and return filtered copy
---
--- @param tbl table The table to filter
--- @param filter function The filtering function, parameters are value, key and table
--- @param preserve_keys boolean? Should the copied table preserve keys or not, default true
---
--- @return List|table
M.filter = function(tbl, filter, preserve_keys)
local out = {}

preserve_keys = preserve_keys and true

for key, val in ipairs(tbl) do
if filter(val, key, tbl) then
if preserve_keys then
out[key] = val
else
table.insert(out, val)
end
end
end

return out
end

--- Make a copy of the table applying the transformation function to each element.
--- Does not preserve the keys of the original table.
---
--- @param tbl table The table to filter
--- @param transform function The transformation function, parameters are value, key and table
---
--- @return List
M.map = function(tbl, transform)
local out = {}

for key, val in ipairs(tbl) do
table.insert(out, transform(val, key, tbl))
end

return out
end

--- Wrapper around nvim_buf_set_lines
---
--- @param buffer integer The target buffer
--- @param block List The list of lines to write
--- @param newline boolean? Add a newline to the end, default false
---
--- @return nil
M.write_block = function(buffer, block, newline)
local content = vim.api.nvim_buf_get_lines(buffer, 0, -1, false)
local first_line = false

if #content == 1 and content[1] == "" then
first_line = true
end

vim.api.nvim_buf_set_lines(buffer, first_line and 0 or -1, -1, false, block)

if newline then
vim.api.nvim_buf_set_lines(buffer, -1, -1, false, { "" })
end
end

--- Split table on the elements where the function returns true
---
--- @param tbl List
--- @param index function
--- @param inclusive boolean? If true the split value is in the first table, default false
---
--- @return List[]
M.split_list = function(tbl, index, inclusive)
local out = { {} }

for key, val in ipairs(tbl) do
if index(val, key, tbl) then
table.insert(out, {})

if inclusive then
table.insert(out[#out - 1], val)
else
table.insert(out[#out], val)
end
else
table.insert(out[#out], val)
end
end

return 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

0 comments on commit e326b56

Please sign in to comment.