Skip to content
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@ use {
result_split_horizontal = false,
-- Skip SSL verification, useful for unknown certificates
skip_ssl_verification = false,
})
-- Highlight request on run
highlight = {
enabled = true,
timeout = 150,
},
-- Jump to request line on run
jump_to_request = false,
})
end
}
```
Expand Down Expand Up @@ -100,6 +107,8 @@ To run `rest.nvim` you should map the following commands:
on vertical)
- `skip_ssl_verification` passes the `-k` flag to cURL in order to skip SSL verification,
useful when using unknown certificates
- `highlight` allows to enable and configure the highlighting of the selected request when send,
- `jump_to_request` moves the cursor to the selected request line when send,

## Usage

Expand Down
7 changes: 7 additions & 0 deletions doc/rest-nvim.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ function, it looks like this by default:
` result_split_horizontal = false,`
` -- Skip SSL verification, useful for unknown certificates`
` skip_ssl_verification = false,`
` -- Highlight request on run`
` highlight = {`
` enabled = true,`
` timeout = 150,`
` },`
` -- Jump to request line on run`
` jump_to_request = false,`
`})`

In this section we will be using `https://reqres.in/` for requests.
Expand Down
5 changes: 5 additions & 0 deletions lua/rest-nvim/config/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ local M = {}
local config = {
result_split_horizontal = false,
skip_ssl_verification = false,
highlight = {
enabled = true,
timeout = 150,
},
jump_to_request = false,
}

--- Get a configuration value
Expand Down
129 changes: 69 additions & 60 deletions lua/rest-nvim/curl/init.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local utils = require("rest-nvim.utils")
local curl = require("plenary.curl")
local config = require("rest-nvim.config")
local log = require("plenary.log").new({ plugin = "rest.nvim", level = "debug" })

local M = {}
-- get_or_create_buf checks if there is already a buffer with the rest run results
Expand Down Expand Up @@ -39,75 +40,83 @@ M.get_or_create_buf = function()
return new_bufnr
end

-- curl_cmd runs curl with the passed options, gets or creates a new buffer
-- and then the results are printed to the recently obtained/created buffer
-- @param opts curl arguments
M.curl_cmd = function(opts)
local res = curl[opts.method](opts)
if opts.dry_run then
print("[rest.nvim] Request preview:\n" .. "curl " .. table.concat(res, " "))
return
end
local function create_callback(method, url)
return function(res)
if res.exit ~= 0 then
log.error("[rest.nvim] " .. utils.curl_error(res.exit))
return
end
local res_bufnr = M.get_or_create_buf()
local json_body = false

if res.exit ~= 0 then
error("[rest.nvim] " .. utils.curl_error(res.exit))
end
-- Check if the content-type is "application/json" so we can format the JSON
-- output later
for _, header in ipairs(res.headers) do
if string.find(header, "application/json") then
json_body = true
break
end
end

--- 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 })

local res_bufnr = M.get_or_create_buf()
local json_body = false
-- HTTP version, status code and its meaning, e.g. HTTP/1.1 200 OK
local line_count = vim.api.nvim_buf_line_count(res_bufnr)
vim.api.nvim_buf_set_lines(
res_bufnr,
line_count,
line_count,
false,
{ "HTTP/1.1 " .. utils.http_status(res.status) }
)
-- Headers, e.g. Content-Type: application/json
vim.api.nvim_buf_set_lines(
res_bufnr,
line_count + 1,
line_count + 1 + #res.headers,
false,
res.headers
)

-- Check if the content-type is "application/json" so we can format the JSON
-- output later
for _, header in ipairs(res.headers) do
if string.find(header, "application/json") then
json_body = true
break
--- Add the curl command results into the created buffer
if json_body then
-- format JSON body
res.body = vim.fn.system("jq", res.body)
end
end
local lines = utils.split(res.body, "\n")
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)

--- 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, { opts.method:upper() .. " " .. opts.url })
-- HTTP version, status code and its meaning, e.g. HTTP/1.1 200 OK
local line_count = vim.api.nvim_buf_line_count(res_bufnr)
vim.api.nvim_buf_set_lines(
res_bufnr,
line_count,
line_count,
false,
{ "HTTP/1.1 " .. utils.http_status(res.status) }
)
-- Headers, e.g. Content-Type: application/json
vim.api.nvim_buf_set_lines(
res_bufnr,
line_count + 1,
line_count + 1 + #res.headers,
false,
res.headers
)
-- Only open a new split if the buffer is not loaded into the current window
if vim.fn.bufwinnr(res_bufnr) == -1 then
local cmd_split = [[vert sb]]
if config.result_split_horizontal == true then
Comment thread
jens1205 marked this conversation as resolved.
Outdated
cmd_split = [[sb]]
end
vim.cmd(cmd_split .. res_bufnr)
-- Set unmodifiable state
vim.api.nvim_buf_set_option(res_bufnr, "modifiable", false)
end

--- Add the curl command results into the created buffer
if json_body then
-- format JSON body
res.body = vim.fn.system("jq", res.body)
-- Send cursor in response buffer to start
utils.move_cursor(res_bufnr, 1)
end
local lines = utils.split(res.body, "\n")
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)
end

-- Only open a new split if the buffer is not loaded into the current window
if vim.fn.bufwinnr(res_bufnr) == -1 then
local cmd_split = [[vert sb]]
if config.result_split_horizontal == true then
cmd_split = [[sb]]
end
vim.cmd(cmd_split .. res_bufnr)
-- Set unmodifiable state
vim.api.nvim_buf_set_option(res_bufnr, "modifiable", false)
-- curl_cmd runs curl with the passed options, gets or creates a new buffer
-- and then the results are printed to the recently obtained/created buffer
-- @param opts curl arguments
M.curl_cmd = function(opts)
if opts.dry_run then
local res = curl[opts.method](opts)
log.debug("[rest.nvim] Request preview:\n" .. "curl " .. table.concat(res, " "))
return
else
opts.callback = vim.schedule_wrap(create_callback(opts.method, opts.url))
curl[opts.method](opts)
end

-- Send cursor in response buffer to start
utils.go_to_line(res_bufnr, 1)
end

return M
12 changes: 12 additions & 0 deletions lua/rest-nvim/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,15 @@ rest.run = function(verbose)
raw = config.skip_ssl_verification and { "-k" } or nil,
body = result.body,
dry_run = verbose or false,
bufnr = result.bufnr,
start_line = result.start_line,
end_line = result.end_line,
}

if config.get("highlight").enabled == true then
Comment thread
jens1205 marked this conversation as resolved.
Outdated
request.highlight(result.bufnr, result.start_line, result.end_line)
end

local success_req, req_err = pcall(curl.curl_cmd, LastOpts)

if not success_req then
Expand All @@ -43,6 +50,11 @@ rest.last = function()
vim.api.nvim_err_writeln("[rest.nvim]: Last request not found")
return
end

if config.get("highlight").enabled == true then
request.highlight(LastOpts.bufnr, LastOpts.start_line, LastOpts.end_line)
end

local success_req, req_err = pcall(curl.curl_cmd, LastOpts)

if not success_req then
Expand Down
57 changes: 50 additions & 7 deletions lua/rest-nvim/request/init.lua
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
local utils = require("rest-nvim.utils")
local path = require("plenary.path")
local log = require("plenary.log").new({ plugin = "rest.nvim", level = "warn" })
local log = require("plenary.log").new({ plugin = "rest.nvim", level = "debug" })
local config = require("rest-nvim.config")

-- get_importfile returns in case of an imported file the absolute filename
-- @param bufnr Buffer number, a.k.a id
-- @param stop_line Line to stop searching
local function get_importfile_name(bufnr, start_line, stop_line)
-- store old cursor position
local oldpos = vim.fn.getcurpos()
utils.go_to_line(bufnr, start_line)
utils.move_cursor(bufnr, start_line)

local import_line = vim.fn.search("^<", "n", stop_line)
-- restore old cursor position
utils.go_to_line(bufnr, oldpos[2])
utils.move_cursor(bufnr, oldpos[2])

if import_line > 0 then
local fileimport_string
Expand Down Expand Up @@ -138,13 +139,19 @@ local function end_request(bufnr)
if linenumber < vim.fn.line("$") then
linenumber = linenumber + 1
end
utils.go_to_line(bufnr, linenumber)
utils.move_cursor(bufnr, linenumber)

local next = vim.fn.search("^GET\\|^POST\\|^PUT\\|^PATCH\\|^DELETE", "cn", vim.fn.line("$"))

-- restore cursor position
utils.go_to_line(bufnr, oldlinenumber)
return next > 1 and next - 1 or vim.fn.line("$")
utils.move_cursor(bufnr, oldlinenumber)
local last_line = vim.fn.line("$")

if next == 0 or (oldlinenumber == last_line) then
return last_line
else
return next - 1
end
end

-- parse_url returns a table with the method of the request and the URL
Expand All @@ -160,27 +167,63 @@ end

local M = {}
M.get_current_request = function()
local curpos = vim.fn.getcurpos()
local bufnr = vim.api.nvim_win_get_buf(0)

local start_line = start_request()
if start_line == 0 then
error("No request found")
end
local end_line = end_request()
utils.go_to_line(bufnr, start_line)

local parsed_url = parse_url(vim.fn.getline(start_line))

local headers, body_start = get_headers(bufnr, start_line, end_line)

local body = get_body(bufnr, body_start, end_line)

if config.get("jump_to_request") == true then
utils.move_cursor(bufnr, start_line)
else
utils.move_cursor(bufnr, curpos[2], curpos[3])
end

return {
method = parsed_url.method,
url = parsed_url.url,
headers = headers,
body = body,
bufnr = bufnr,
start_line = start_line,
end_line = end_line,
}
end

local select_ns = vim.api.nvim_create_namespace("rest-nvim")
M.highlight = function(bufnr, start_line, end_line)
local opts = config.get("highlight") or {}
local higroup = "IncSearch"
local timeout = opts.timeout or 150

vim.api.nvim_buf_clear_namespace(bufnr, select_ns, 0, -1)

local end_column = string.len(vim.fn.getline(end_line))

vim.highlight.range(
bufnr,
select_ns,
higroup,
{ start_line - 1, 0 },
{ end_line - 1, end_column },
"c",
false
)

vim.defer_fn(function()
if vim.api.nvim_buf_is_valid(bufnr) then
vim.api.nvim_buf_clear_namespace(bufnr, select_ns, 0, -1)
end
end, timeout)
end

return M
10 changes: 6 additions & 4 deletions lua/rest-nvim/utils/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ math.randomseed(os.time())

local M = {}

-- go_to_line moves the cursor to the desired line in the provided buffer
-- move_cursor moves the cursor to the desired position in the provided buffer
-- @param bufnr Buffer number, a.k.a id
-- @param line the desired cursor position
M.go_to_line = function(bufnr, line)
-- @param line the desired line
-- @param column the desired column, defaults to 1
M.move_cursor = function(bufnr, line, column)
column = column or 1
vim.api.nvim_buf_call(bufnr, function()
vim.fn.cursor(line, 1)
vim.fn.cursor(line, column)
end)
end

Expand Down
2 changes: 1 addition & 1 deletion tests/external_file/multiple_requests.http
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ Content-Type: application/json
< ./user.json

####

###
GET https://reqres.in/api/users?page=5