Skip to content

Commit 6a7699b

Browse files
feat: basic :Rest curl command
1 parent 1e92829 commit 6a7699b

File tree

3 files changed

+121
-2
lines changed

3 files changed

+121
-2
lines changed

lua/rest-nvim/client/curl/cli.lua

+16-2
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,9 @@ builder.STAT_ARGS = builder.statistics()
268268

269269
---build curl request arguments based on Request object
270270
---@param req rest.Request
271+
---@param ignore_stats? boolean
271272
---@return string[] args
272-
function builder.build(req)
273+
function builder.build(req, ignore_stats)
273274
local args = {}
274275
---@param list table
275276
---@param value any
@@ -296,10 +297,23 @@ function builder.build(req)
296297
end
297298
-- TODO: auth?
298299
insert(args, builder.http_version(req.http_version) or {})
299-
insert(args, builder.STAT_ARGS)
300+
if not ignore_stats then
301+
insert(args, builder.STAT_ARGS)
302+
end
300303
return vim.iter(args):flatten(math.huge):totable()
301304
end
302305

306+
---Generate curl command equivelant to given request.
307+
---This command doesn't include verbose/trace options
308+
---@param req rest.Request
309+
function builder.build_command(req)
310+
local base_cmd = "curl -sL"
311+
local args = vim.iter(builder.build(req, true)):map(function (a)
312+
return vim.fn.shellescape(a)
313+
end)
314+
return base_cmd .. " " .. args:join(" ")
315+
end
316+
303317
---Send request via `curl` cli
304318
---@param request rest.Request Request data to be passed to cURL
305319
---@return nio.control.Future future Future containing rest.Response

lua/rest-nvim/commands.lua

+78
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
--- env set {path} Register environment file to current `.http` file.
3030
--- `path` should be relative to Neovim's cwd
3131
---
32+
--- curl yank {name?} (experimental) Copy curl command equivelant to HTTP
33+
--- request with given `name`. If no name is provided, copy
34+
--- from request under the cursor.
35+
---
36+
--- curl comment {name?} (experimental) Similar to `:Rest curl yank` but instead
37+
--- copying command to clipboard, directly insert curl
38+
--- command as a comment.
39+
---
3240
--- NOTE: All `:Rest` commands opening new window support |command-modifiers|.
3341
--- For example, you can run `:hor Rest open` to open result pane in horizontal
3442
--- split
@@ -174,6 +182,76 @@ local rest_command_tbl = {
174182
return match
175183
end,
176184
},
185+
-- TODO(boltless): complete curl command
186+
curl = {
187+
impl = function (args, _)
188+
if args[1] == "yank" then
189+
local req_node
190+
if not args[2] then
191+
req_node = parser().get_cursor_request_node()
192+
if not req_node then
193+
logger().error("failed to find request at cursor position")
194+
vim.notify("[rest.nvim] failed to find request at cursor position", vim.log.levels.ERROR)
195+
return
196+
end
197+
else
198+
req_node = parser().get_request_node_by_name(args[2])
199+
if not req_node then
200+
logger().error("failed to find request with name:" .. args[2])
201+
vim.notify("[rest.nvim] failed to find request with name:" .. args[2], vim.log.levels.ERROR)
202+
return
203+
end
204+
end
205+
local req = parser().parse(req_node, 0)
206+
if not req then
207+
logger().error("failed to parse request")
208+
vim.notify("[rest.nvim] failed to parse request. See `:Rest logs` for more info", vim.log.levels.ERROR)
209+
return
210+
end
211+
local curl_command = require("rest-nvim.client.curl.cli").builder.build_command(req)
212+
vim.fn.setreg("+", curl_command)
213+
vim.notify("[rest.nvim] Copied curl command to clipboard", vim.log.levels.INFO)
214+
elseif args[1] == "comment" then
215+
local req_node
216+
if not args[2] then
217+
req_node = parser().get_cursor_request_node()
218+
if not req_node then
219+
logger().error("failed to find request at cursor position")
220+
vim.notify("[rest.nvim] failed to find request at cursor position", vim.log.levels.ERROR)
221+
return
222+
end
223+
else
224+
req_node = parser().get_request_node_by_name(args[2])
225+
if not req_node then
226+
logger().error("failed to find request with name:" .. args[2])
227+
vim.notify("[rest.nvim] failed to find request with name:" .. args[2], vim.log.levels.ERROR)
228+
return
229+
end
230+
end
231+
local req = parser().parse(req_node, 0)
232+
if not req then
233+
logger().error("failed to parse request")
234+
vim.notify("[rest.nvim] failed to parse request. See `:Rest logs` for more info", vim.log.levels.ERROR)
235+
return
236+
end
237+
local curl_command = require("rest-nvim.client.curl.cli").builder.build_command(req)
238+
local start = req_node:range()
239+
local end_ = start
240+
vim.api.nvim_buf_set_lines(0, start, end_, false, vim.tbl_map(function (line) return "# " .. line end, vim.split(curl_command, "\n")))
241+
-- elseif args[1] == "to-http" then
242+
-- -- TODO: convert comment with curl to http request and insert it below
243+
else
244+
vim.notify("Invalid action '" .. args[1] .. "' provided to 'curl' command", vim.log.levels.ERROR)
245+
end
246+
end,
247+
complete = function (_args)
248+
return {
249+
"yank",
250+
"comment",
251+
-- "to-http",
252+
}
253+
end
254+
}
177255
}
178256

179257
local function rest(opts)

spec/client/curl/command_spec.lua

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---@module 'luassert'
2+
3+
require("spec.minimum_init")
4+
5+
local function open(path)
6+
vim.cmd.edit(path)
7+
-- FIXME: why runtimepath is not working?
8+
vim.bo.filetype = "http"
9+
return 0
10+
end
11+
12+
vim.cmd.source("plugin/rest-nvim.lua")
13+
14+
---@diagnostic disable-next-line: duplicate-set-field
15+
vim.notify = function () end
16+
17+
describe(":Rest curl", function ()
18+
assert(vim.g.loaded_rest_nvim)
19+
it("yank cursor position", function ()
20+
open("spec/examples/basic_get.http")
21+
vim.cmd("Rest curl yank")
22+
assert.same(
23+
"curl -sL 'https://api.github.com/users/boltlessengineer' '-X' 'GET' '-H' 'User-Agent: neovim'",
24+
vim.fn.getreg("+")
25+
)
26+
end)
27+
end)

0 commit comments

Comments
 (0)