From fe1bc20d5ccb60e000e3579ba3aeef5d82ca7637 Mon Sep 17 00:00:00 2001 From: Sotiris Dimitrakopoulos Date: Sat, 5 Oct 2024 22:59:04 +0200 Subject: [PATCH 1/5] add option to re-run last command and also show url as part of the headers --- lua/hurl/main.lua | 20 +++++++++++++ lua/hurl/popup.lua | 7 +++-- lua/hurl/split.lua | 4 ++- lua/hurl/utils.lua | 75 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 4 deletions(-) diff --git a/lua/hurl/main.lua b/lua/hurl/main.lua index 70d6f55..588b63b 100644 --- a/lua/hurl/main.lua +++ b/lua/hurl/main.lua @@ -126,11 +126,15 @@ local on_output = function(code, data, event) end end +local last_request_opts = nil --- Call hurl command ---@param opts table The options ---@param callback? function The callback function local function execute_hurl_cmd(opts, callback) -- Check if a request is currently running + + last_request_opts = opts + if is_running then utils.log_info('hurl: request is already running') utils.notify('hurl: request is running. Please try again later.', vim.log.levels.INFO) @@ -200,6 +204,10 @@ local function execute_hurl_cmd(opts, callback) utils.log_info('hurl: running command' .. vim.inspect(cmd)) + local url = utils.get_url_from_hurl_file(opts[1]) + url = utils.convert_url_to_proper_format(opts, url) + + response.url = url vim.fn.jobstart(cmd, { on_stdout = callback or (is_json_mode and on_json_output or on_output), on_stderr = callback or (is_json_mode and on_json_output or on_output), @@ -297,6 +305,7 @@ local function run_lines(lines, opts, callback) -- Clean up the temporary file after a delay local timeout = 1000 vim.defer_fn(function() + last_request_opts = vim.deepcopy(lines) local success = os.remove(fname) if not success then utils.log_info('hurl: remove file failed ' .. fname) @@ -581,6 +590,17 @@ function M.setup() nargs = '*', range = true, }) + + utils.create_cmd('HurlRerun', function() + if last_request_opts then + run_lines(last_request_opts, {}) + else + utils.log_info('No last request to re-run') + end + end, { + nargs = '*', + range = true, + }) end return M diff --git a/lua/hurl/popup.lua b/lua/hurl/popup.lua index 3f9031a..9debfa3 100644 --- a/lua/hurl/popup.lua +++ b/lua/hurl/popup.lua @@ -83,7 +83,9 @@ M.show = function(data, type) popups.bottom:map('n', _HURL_GLOBAL_CONFIG.mappings.prev_panel, function() vim.api.nvim_set_current_win(popups.top.winid) end) - + if data.url then + data.headers['url'] = data.url + end -- Add headers to the top local headers_table = utils.render_header_table(data.headers) -- Hide header block if empty headers @@ -95,7 +97,6 @@ M.show = function(data, type) end end - -- Add response time as virtual text vim.api.nvim_buf_set_extmark( popups.top.bufnr, vim.api.nvim_create_namespace('response_time_ns'), @@ -104,7 +105,7 @@ M.show = function(data, type) { end_line = 1, id = 1, - virt_text = { { 'Response: ' .. data.response_time .. ' ms', 'Comment' } }, + virt_text = { { 'Responsezz: ' .. data.response_time .. ' ms', 'Comment' } }, virt_text_pos = 'eol', } ) diff --git a/lua/hurl/split.lua b/lua/hurl/split.lua index abc0e2c..a131313 100644 --- a/lua/hurl/split.lua +++ b/lua/hurl/split.lua @@ -34,7 +34,9 @@ M.show = function(data, type) quit() end) end - + if data.url then + data.headers['url'] = data.url + end -- Add headers to the top local headers_table = utils.render_header_table(data.headers) -- Hide header block if empty headers diff --git a/lua/hurl/utils.lua b/lua/hurl/utils.lua index c342ceb..f18b0ea 100644 --- a/lua/hurl/utils.lua +++ b/lua/hurl/utils.lua @@ -312,5 +312,80 @@ util.has_file_in_opts = function(opts) return false end +-- Function to extract the URL from the .hurl file +util.get_url_from_hurl_file = function(file_path) + local url = nil + local file = io.open(file_path, 'r') + + if file then + for line in file:lines() do + line = line:gsub('^%s*(.-)%s*$', '%1') + line = line:gsub('%s+', ' ') + -- NOTE: somehow i can not make regex work here + local matchcase = string.find(line, 'GET ') + or string.find(line, 'POST ') + or string.find(line, 'PUT ') + or string.find(line, 'DELETE ') + or string.find(line, 'PATCH ') + if matchcase then + return line + end + end + file:close() + else + util.log_info('Could not open file: ' .. file_path) + end + + return url +end + +util.convert_url_to_proper_format = function(opts, url) + -- Assuming `url` is defined earlier in the code + if url and url:find('{{') then -- Check if url contains '{{' + local env_file + + -- Find the environment file in the opts that ends with .env + for _, opt in ipairs(opts) do + if opt:match('%.env$') then -- Check if the option ends with .env + env_file = opt + break -- Exit the loop once the first .env file is found + end + end + if env_file then + -- Read the environment file and get the variables + local env_vars = {} + local file = io.open(env_file, 'r') + + if not file then + util.log_error('Could not open environment file: ' .. env_file) + else + -- Read each line of the file + for line in file:lines() do + -- Skip empty lines and comments + line = line:match('^%s*(.-)%s*$') -- Trim whitespace + if line ~= '' and not line:match('^#') then + local key, value = line:match('^(%S+)%s*=%s*(.+)$') -- Match key=value + if key and value then + -- Trim quotes from value, if present + value = value:gsub('^"%s*', ''):gsub('"%s*$', ''):gsub("^'%s*", ''):gsub("'%s*$", '') + env_vars[key] = value + end + end + end + file:close() + end + + for key, value in pairs(env_vars) do + if url:find('{{' .. key .. '}}') then + url = url:gsub('{{' .. key .. '}}', value) + end + end + else + util.log_error('No environment file found in opts.') + end + -- Load environment variables from the found env_file + end + return url +end return util From aff0bb98205ce1924cbb1f6589fed86b37e2960d Mon Sep 17 00:00:00 2001 From: Sotiris Dimitrakopoulos Date: Sun, 6 Oct 2024 10:41:00 +0200 Subject: [PATCH 2/5] make url part of parameters and optional --- lua/hurl/init.lua | 4 ++++ lua/hurl/main.lua | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lua/hurl/init.lua b/lua/hurl/init.lua index 826abb6..e9d359a 100644 --- a/lua/hurl/init.lua +++ b/lua/hurl/init.lua @@ -5,6 +5,10 @@ local default_config = { mode = 'split', show_notification = false, auto_close = true, + url = { + show = true, + format_without_params = true, + }, -- Default split options split_position = 'right', split_size = '50%', diff --git a/lua/hurl/main.lua b/lua/hurl/main.lua index 588b63b..6ebec58 100644 --- a/lua/hurl/main.lua +++ b/lua/hurl/main.lua @@ -204,10 +204,14 @@ local function execute_hurl_cmd(opts, callback) utils.log_info('hurl: running command' .. vim.inspect(cmd)) - local url = utils.get_url_from_hurl_file(opts[1]) - url = utils.convert_url_to_proper_format(opts, url) + if _HURL_GLOBAL_CONFIG.url.show then + local url = utils.get_url_from_hurl_file(opts[1]) + if _HURL_GLOBAL_CONFIG.url.format_without_params then + url = utils.convert_url_to_proper_format(opts, url) + end + response.url = url + end - response.url = url vim.fn.jobstart(cmd, { on_stdout = callback or (is_json_mode and on_json_output or on_output), on_stderr = callback or (is_json_mode and on_json_output or on_output), From d7e952a0cba6773594e911acdf4ce095234a4072 Mon Sep 17 00:00:00 2001 From: Sotiris Dimitrakopoulos Date: Sun, 6 Oct 2024 10:49:31 +0200 Subject: [PATCH 3/5] rename and make popup work --- lua/hurl/popup.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/hurl/popup.lua b/lua/hurl/popup.lua index 9debfa3..088133d 100644 --- a/lua/hurl/popup.lua +++ b/lua/hurl/popup.lua @@ -105,7 +105,7 @@ M.show = function(data, type) { end_line = 1, id = 1, - virt_text = { { 'Responsezz: ' .. data.response_time .. ' ms', 'Comment' } }, + virt_text = { { 'Response: ' .. data.response_time .. ' ms', 'Comment' } }, virt_text_pos = 'eol', } ) From d4dffb604784f0867a10522d4bc81315353d1ad4 Mon Sep 17 00:00:00 2001 From: Sotiris Dimitrakopoulos Date: Mon, 7 Oct 2024 20:55:44 +0200 Subject: [PATCH 4/5] close file to avoid memory issues --- lua/hurl/utils.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lua/hurl/utils.lua b/lua/hurl/utils.lua index f18b0ea..5130ad6 100644 --- a/lua/hurl/utils.lua +++ b/lua/hurl/utils.lua @@ -328,6 +328,7 @@ util.get_url_from_hurl_file = function(file_path) or string.find(line, 'DELETE ') or string.find(line, 'PATCH ') if matchcase then + file:close() return line end end From f817207cbb1777b92eab45757f936c6192b0f2fb Mon Sep 17 00:00:00 2001 From: "Dung Duc Huynh (Kaka)" <870029+jellydn@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:23:25 +0800 Subject: [PATCH 5/5] Update lua/hurl/utils.lua Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- lua/hurl/utils.lua | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lua/hurl/utils.lua b/lua/hurl/utils.lua index 5130ad6..0e349c5 100644 --- a/lua/hurl/utils.lua +++ b/lua/hurl/utils.lua @@ -321,13 +321,8 @@ util.get_url_from_hurl_file = function(file_path) for line in file:lines() do line = line:gsub('^%s*(.-)%s*$', '%1') line = line:gsub('%s+', ' ') - -- NOTE: somehow i can not make regex work here - local matchcase = string.find(line, 'GET ') - or string.find(line, 'POST ') - or string.find(line, 'PUT ') - or string.find(line, 'DELETE ') - or string.find(line, 'PATCH ') - if matchcase then + local method = line:match('^(%u+)%s') + if method and method:match('^(GET|POST|PUT|DELETE|PATCH)$') then file:close() return line end