Skip to content

Commit

Permalink
Run hurl cmd at current line (#13)
Browse files Browse the repository at this point in the history
* refactor: add formatter options

* chore: migrate to new global config table

* refactor: use cache to save log file

* feat: run hurl cmd at current line

* docs: add new usage for run Hurl at current line
  • Loading branch information
jellydn authored Oct 30, 2023
1 parent 0d8f75d commit ba68b4f
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 33 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ Add the following configuration to your Neovim setup:
```lua
{
"jellydn/hurl.nvim",
ft = "hurl",
dependencies = { "MunifTanjim/nui.nvim" },
cmd = { "HurlRunner" },
cmd = { "HurlRunner", "HurlRunnerAt" },
opts = {
-- Show debugging info
debug = false,
Expand All @@ -27,9 +26,10 @@ Add the following configuration to your Neovim setup:
},
keys = {
-- Run API request
{ "<leader>ra", "<cmd>HurlRunner<CR>", desc = "Run API requests" },
-- Run API request in visual mode
{ "<leader>cr", ":HurlRunner<CR>", desc = "Run API request", mode = "v" },
{ "<leader>rA", "<cmd>HurlRunner<CR>", desc = "Run All requests" },
{ "<leader>ra", "<cmd>HurlRunnerAt<CR>", desc = "Run Api request" },
-- Run Hurl request in visual mode
{ "<leader>h", ":HurlRunner<CR>", desc = "Hurl Runner", mode = "v" },
},
}
}
Expand Down
12 changes: 10 additions & 2 deletions lua/hurl/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@
local default_config = {
debug = false,
mode = 'split',
formatters = {
json = { 'jq' },
html = {
'prettier',
'--parser',
'html',
},
},
}
--- Global configuration for entire plugin, easy to access from anywhere
_HURL_CFG = default_config
_HURL_GLOBAL_CONFIG = default_config
local M = {}

--- Setup hurl.nvim
---@param options (table | nil)
-- - debug: (boolean | nil) default: false.
-- - mode: ('popup' | 'split') default: popup.
function M.setup(options)
_HURL_CFG = vim.tbl_extend('force', _HURL_CFG, options or default_config)
_HURL_GLOBAL_CONFIG = vim.tbl_extend('force', _HURL_GLOBAL_CONFIG, options or default_config)

require('hurl.main').setup()
end
Expand Down
98 changes: 82 additions & 16 deletions lua/hurl/main.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local util = require('hurl.utils')
local utils = require('hurl.utils')

local M = {}

Expand All @@ -7,7 +7,6 @@ local response = {}
--- Output handler
---@class Output
local on_output = function(code, data, event)
util.log_info('hurl: code ', code)
local head_state
if data[1] == '' then
table.remove(data, 1)
Expand All @@ -18,7 +17,7 @@ local on_output = function(code, data, event)

if event == 'stderr' and #data > 1 then
response.body = data
util.log_error(vim.inspect(data))
utils.log_error(vim.inspect(data))
response.raw = data
response.headers = {}
return
Expand Down Expand Up @@ -49,9 +48,9 @@ local on_output = function(code, data, event)
end
response.raw = data

util.log_info('hurl: response status ' .. response.status)
util.log_info('hurl: response headers ' .. vim.inspect(response.headers))
util.log_info('hurl: response body ' .. response.body)
utils.log_info('hurl: response status ' .. response.status)
utils.log_info('hurl: response headers ' .. vim.inspect(response.headers))
utils.log_info('hurl: response body ' .. response.body)
end

--- Call hurl command
Expand All @@ -62,11 +61,15 @@ local function request(opts, callback)
local cmd = vim.list_extend({ 'hurl', '-i', '--no-color' }, opts)
response = {}

if _HURL_GLOBAL_CONFIG.debug then
vim.fn.setqflist({ { filename = vim.inspect(cmd), text = vim.inspect(opts) } })
end

vim.fn.jobstart(cmd, {
on_stdout = on_output,
on_stderr = on_output,
on_exit = function(i, code)
util.log_info('exit at ' .. i .. ' , code ' .. code)
utils.log_info('exit at ' .. i .. ' , code ' .. code)
if code ~= 0 then
-- Send error code and response to quickfix and open it
vim.fn.setqflist({ { filename = vim.inspect(cmd), text = vim.inspect(response.body) } })
Expand All @@ -84,12 +87,17 @@ local function request(opts, callback)
return
end

local container = require('hurl.' .. _HURL_CFG.mode)
--show body if it is json
if util.is_json_response(response.headers['content-type']) then
local container = require('hurl.' .. _HURL_GLOBAL_CONFIG.mode)
local content_type = response.headers['content-type']
or response.headers['Content-Type']
or ''

utils.log_info('Detected content type: ' .. content_type)

if utils.is_json_response(content_type) then
container.show(response, 'json')
else
if util.is_html_response(response.headers['content-type']) then
if utils.is_html_response(content_type) then
container.show(response, 'html')
else
container.show(response, 'text')
Expand All @@ -113,11 +121,11 @@ end
---@param opts table The options
local function run_selection(opts)
opts = opts or {}
local lines = util.get_visual_selection()
local lines = utils.get_visual_selection()
if not lines then
return
end
local fname = util.create_tmp_file(lines)
local fname = utils.create_tmp_file(lines)

if not fname then
vim.notify('hurl: create tmp file failed. Please try again!', vim.log.levels.WARN)
Expand All @@ -126,24 +134,82 @@ local function run_selection(opts)

table.insert(opts, fname)
request(opts)

-- Clean tmp file after 1s
local timeout = 1000
vim.defer_fn(function()
local success = os.remove(fname)
if not success then
vim.notify('hurl: remove file failed', vim.log.levels.WARN)
else
util.log_info('hurl: remove file success ' .. fname)
utils.log_info('hurl: remove file success ' .. fname)
end
end, 1000)
end, timeout)
end

local function find_http_verb(line, current_line_number)
if not line then
return nil
end

-- TODO: Support other HTTP verbs
local verb_start, verb_end = line:find('GET')
if not verb_start then
verb_start, verb_end = line:find('POST')
end

if verb_start then
return { line_number = current_line_number, start_pos = verb_start, end_pos = verb_end }
else
return nil
end
end

local function find_http_verb_positions_in_buffer()
local buf = vim.api.nvim_get_current_buf()
local total_lines = vim.api.nvim_buf_line_count(buf)
local cursor = vim.api.nvim_win_get_cursor(0)
local current_line_number = cursor[1]

local total = 0
local current = 0

for i = 1, total_lines do
local line = vim.api.nvim_buf_get_lines(buf, i - 1, i, false)[1]
local result = find_http_verb(line)
if result ~= nil then
total = total + 1
if i == current_line_number then
current = total
end
end
end

return {
total = total,
current = current,
}
end

function M.setup()
util.create_cmd('HurlRunner', function(opts)
utils.create_cmd('HurlRunner', function(opts)
if opts.range ~= 0 then
run_selection(opts.fargs)
else
run_current_file(opts.fargs)
end
end, { nargs = '*', range = true })

utils.create_cmd('HurlRunnerAt', function(opts)
local result = find_http_verb_positions_in_buffer()
if result.current > 0 then
opts.fargs = opts.fargs or {}
opts.fargs = vim.list_extend(opts.fargs, { '--to-entry', result.current })
run_current_file(opts.fargs)
else
vim.notify('No GET/POST found in the current line')
end
end, { nargs = '*', range = true })
end

return M
9 changes: 5 additions & 4 deletions lua/hurl/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ local util = {}
---@vararg any
util.log_info = function(...)
-- Only save log when debug is on
if not _HURL_CFG.debug then
if not _HURL_GLOBAL_CONFIG.debug then
return
end

Expand All @@ -17,7 +17,7 @@ end
---@vararg any
util.log_error = function(...)
-- Only save log when debug is on
if not _HURL_CFG.debug then
if not _HURL_GLOBAL_CONFIG.debug then
return
end

Expand Down Expand Up @@ -69,7 +69,7 @@ util.create_tmp_file = function(content)
f:close()

-- Send to quicklist to open the temp file in debug mode
if _HURL_CFG.debug then
if _HURL_GLOBAL_CONFIG.debug then
vim.fn.setqflist({ { filename = tmp_file, text = 'hurl.nvim' } })
vim.cmd('copen')
end
Expand All @@ -91,7 +91,8 @@ end
---@param type 'json' | 'html' | 'text'
---@return string[] | nil
util.format = function(body, type)
local formatters = { json = { 'jq' }, html = { 'prettier', '--parser', 'html' } }
local formatters = _HURL_GLOBAL_CONFIG.formatters
or { json = { 'jq' }, html = { 'prettier', '--parser', 'html' } }

-- If no formatter is defined, return the body
if not formatters[type] then
Expand Down
3 changes: 1 addition & 2 deletions lua/hurl/vlog.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ local unpack = unpack or table.unpack
log.new = function(config, standalone)
config = vim.tbl_deep_extend('force', default_config, config)

local outfile =
string.format('%s/%s.log', vim.api.nvim_call_function('stdpath', { 'data' }), config.plugin)
local outfile = string.format('%s/%s.log', vim.fn.stdpath('cache'), config.plugin)

local obj
if standalone then
Expand Down
4 changes: 4 additions & 0 deletions test/hurl_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ describe('Hurl wrapper', function()
it('should define a custom command: HurlRunner', function()
assert.truthy(vim.fn.exists(':HurlRunner'))
end)

it('should define a custom command: HurlRunnerAt', function()
assert.truthy(vim.fn.exists(':HurlRunnerAt'))
end)
end)
8 changes: 4 additions & 4 deletions test/plugin_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ describe('Hurl.nvim plugin', function()
local hurl = require('hurl')
assert.truthy(hurl)

assert.are.same('split', _HURL_CFG.mode)
assert.are.same(false, _HURL_CFG.debug)
assert.are.same('split', _HURL_GLOBAL_CONFIG.mode)
assert.are.same(false, _HURL_GLOBAL_CONFIG.debug)
end)

it('should be able parse the configuration file', function()
Expand All @@ -13,7 +13,7 @@ describe('Hurl.nvim plugin', function()
mode = 'popup',
})

assert.are.same('popup', _HURL_CFG.mode)
assert.are.same(true, _HURL_CFG.debug)
assert.are.same('popup', _HURL_GLOBAL_CONFIG.mode)
assert.are.same(true, _HURL_GLOBAL_CONFIG.debug)
end)
end)

0 comments on commit ba68b4f

Please sign in to comment.