diff --git a/README.md b/README.md index 0af1847..8002b5a 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ## Features - 🚀 Execute HTTP requests directly from `.hurl` files. -- 👁‍🗨 Multiple display modes for API response: popup or quickfix. +- 👁‍🗨 Multiple display modes for API response: popup or split. - 🌈 Highly customizable through Neovim settings. ## Usage @@ -38,7 +38,7 @@ Add the following configuration to your Neovim setup: -- Show debugging info debug = true, -- Show response in popup or in quick list - -- popup | quickfix + -- popup | split mode = "popup", -- }, keys = { diff --git a/hurl.txt b/hurl.txt index 5353165..64553bd 100644 --- a/hurl.txt +++ b/hurl.txt @@ -1,4 +1,9 @@ nvim +quickfix +autocmd +systemlist +bufnr +winid vlog vararg getpos @@ -17,18 +22,14 @@ setqflist copen fargs nargs +Neovim +jellydn +Munif +Tanjim +Huynh +kofi +buymeacoffee docstrings sweepai pygithub -sandboxed -jellydn -quickfix' -systemlist -bufnr -Tanjim -quickfix -Munif -autocmd -keymap -noremap -winid +sandboxed \ No newline at end of file diff --git a/lua/hurl/init.lua b/lua/hurl/init.lua index 0700eac..e0c2ba0 100644 --- a/lua/hurl/init.lua +++ b/lua/hurl/init.lua @@ -1,11 +1,6 @@ --- Global configuration for hurl.nvim _HURL_CFG = { - -- Debug mode - -- Default: false debug = false, - - -- Display in a floating window or in a quick fix list - -- Default is popup mode = 'popup', } local M = {} @@ -13,7 +8,7 @@ local M = {} --- Setup hurl.nvim ---@param options (table | nil) -- - debug: (boolean | nil) default: false. --- - mode: ('popup' | 'quickfix') default: popup. +-- - mode: ('popup' | 'split') default: popup. function M.setup(options) _HURL_CFG = vim.tbl_extend('force', _HURL_CFG, options or {}) diff --git a/lua/hurl/popup.lua b/lua/hurl/popup.lua index 8a3abf5..e47f649 100644 --- a/lua/hurl/popup.lua +++ b/lua/hurl/popup.lua @@ -28,20 +28,6 @@ local layout = Layout( }, { dir = 'col' }) ) ---- Format the body of the request ----@param body string ----@param type 'json' | 'html' ----@return string[] | nil -local function format(body, type) - local formatters = { json = 'jq', html = { 'prettier', '--parser', 'html' } } - local stdout = vim.fn.systemlist(formatters[type], body) - if vim.v.shell_error ~= 0 then - utils.log('formatter failed' .. tostring(vim.v.shell_error)) - return nil - end - return stdout -end - -- Show content in a popup ---@param data table --- - body string @@ -85,23 +71,17 @@ M.show = function(data, type) end) -- Add headers to the top - local headers = {} - local line = 0 - for k, v in pairs(data.headers) do - line = line + 1 - table.insert(headers, k .. ': ' .. v) - end - + local headers_table = utils.render_header_table(data.headers) -- Hide header block if empty headers - if line == 0 then + if headers_table.line == 0 then vim.api.nvim_win_close(popups.top.winid, true) else - if line > 0 then - vim.api.nvim_buf_set_lines(popups.top.bufnr, 0, 1, false, headers) + if headers_table.line > 0 then + vim.api.nvim_buf_set_lines(popups.top.bufnr, 0, 1, false, headers_table.headers) end end - local content = format(data.body, type) + local content = utils.format(data.body, type) if not content then return end diff --git a/lua/hurl/split.lua b/lua/hurl/split.lua new file mode 100644 index 0000000..a93147b --- /dev/null +++ b/lua/hurl/split.lua @@ -0,0 +1,51 @@ +local Split = require('nui.split') +local event = require('nui.utils.autocmd').event + +local split = Split({ + relative = 'editor', + position = 'bottom', + size = '30%', +}) + +local utils = require('hurl.utils') + +local M = {} + +-- Show content in a popup +---@param data table +--- - body string +--- - headers table +---@param type 'json' | 'html' +M.show = function(data, type) + -- mount/open the component + split:mount() + + -- unmount component when cursor leaves buffer + split:on(event.BufLeave, function() + split:unmount() + end) + + -- Add headers to the top + local headers_table = utils.render_header_table(data.headers) + -- Hide header block if empty headers + if headers_table.line == 0 then + utils.log('no headers') + else + if headers_table.line > 0 then + vim.api.nvim_buf_set_lines(split.bufnr, 0, 1, false, headers_table.headers) + end + end + + local content = utils.format(data.body, type) + if not content then + return + end + + -- Set content to highlight + vim.api.nvim_buf_set_option(split.bufnr, 'filetype', type) + + -- Add content to the bottom + vim.api.nvim_buf_set_lines(split.bufnr, headers_table.line, -1, false, content) +end + +return M diff --git a/lua/hurl/utils.lua b/lua/hurl/utils.lua index 88ee72c..f746399 100644 --- a/lua/hurl/utils.lua +++ b/lua/hurl/utils.lua @@ -62,4 +62,48 @@ util.create_cmd = function(cmd, func, opt) vim.api.nvim_create_user_command(cmd, func, opt) end +--- Format the body of the request +---@param body string +---@param type 'json' | 'html' +---@return string[] | nil +util.format = function(body, type) + local formatters = { json = 'jq', html = { 'prettier', '--parser', 'html' } } + local stdout = vim.fn.systemlist(formatters[type], body) + if vim.v.shell_error ~= 0 then + util.log('formatter failed' .. tostring(vim.v.shell_error)) + return nil + end + return stdout +end + +--- Render header table +---@param headers table +util.render_header_table = function(headers) + local result = {} + local maxKeyLength = 0 + for k, _ in pairs(headers) do + maxKeyLength = math.max(maxKeyLength, #k) + end + + local line = 0 + for k, v in pairs(headers) do + line = line + 1 + if line == 1 then + -- Add header for the table view + table.insert( + result, + string.format('%-' .. maxKeyLength .. 's | %s', 'Header Key', 'Header Value') + ) + + line = line + 1 + end + table.insert(result, string.format('%-' .. maxKeyLength .. 's | %s', k, v)) + end + + return { + line = line, + headers = result, + } +end + return util diff --git a/lua/hurl/wrapper.lua b/lua/hurl/wrapper.lua index 9738b39..7bc0009 100644 --- a/lua/hurl/wrapper.lua +++ b/lua/hurl/wrapper.lua @@ -97,12 +97,14 @@ local function request(opts, callback) else popup.show(response, 'html') end - elseif _HURL_CFG.mode == 'quickfix' then - vim.fn.setqflist({}, ' ', { - title = 'hurl finished', - lines = lines, - }) - vim.cmd('copen') + elseif _HURL_CFG.mode == 'split' then + local split = require('hurl.split') + --show body if it is json + if response.headers['content-type'] == 'application/json' then + split.show(response, 'json') + else + split.show(response, 'html') + end end end end,