Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refactor writing to buffer #260

Merged
merged 3 commits into from
Nov 27, 2023
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
76 changes: 38 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,28 @@ 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*$")

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 = res.headers[utils.key(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 +152,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 +220,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
93 changes: 92 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 @@ -417,6 +417,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
Loading