Skip to content

Commit

Permalink
feat: Add treesitter support (#103)
Browse files Browse the repository at this point in the history
This PR uses treesitter hurl parser to locate the HURL entry at the
current cursor position. This is more efficient and reliable than
parsing based on HTTP verbs and allows executing HurlRunnerAt from any
place as long as it is inside a HURL entry.
  • Loading branch information
hsanson authored Mar 9, 2024
1 parent b829cda commit 6a16d4f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 43 deletions.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ Add the following configuration to your Neovim setup with [lazy.nvim](https://gi
```lua
{
"jellydn/hurl.nvim",
dependencies = { "MunifTanjim/nui.nvim" },
dependencies = {
"MunifTanjim/nui.nvim",
"nvim-treesitter/nvim-treesitter"
},
ft = "hurl",
opts = {
-- Show debugging info
Expand Down Expand Up @@ -56,6 +59,9 @@ Add the following configuration to your Neovim setup with [lazy.nvim](https://gi
}
```

When configuring nvim-treesitter add `hurl` to the `ensure_installed` list of
parsers.

Simple demo in split mode:

[![Show in split mode](https://i.gyazo.com/19492e8b5366cec3f22d5fd97a63f37a.gif)](https://gyazo.com/19492e8b5366cec3f22d5fd97a63f37a)
Expand Down Expand Up @@ -127,7 +133,7 @@ Select a range of lines and press `<leader>h` to execute the request or run `Hur

### Run at current line

Place your cursor on the line you want to run and press `<leader>a` or run `HurlRunnerAt` command to execute the request. It need be one of the HTTP methods listed: GET, POST, PUT, DELETE, PATCH.
Place your cursor on a HURL entry and press `<leader>a` or run `HurlRunnerAt` command to execute the entry request.

[![Run at current line in popup mode](https://i.gyazo.com/20efd2cf3f73238bd57e79fc662208b1.gif)](https://gyazo.com/20efd2cf3f73238bd57e79fc662208b1)

Expand All @@ -139,11 +145,11 @@ Run `HurlVerbose` command to execute the request in verbose mode. The response w

### Run to entry

Place your cursor on the line you want to run to that entry and press `<leader>te` or run `HurlRunnerToEntry` command to execute the request. It need be one of the HTTP methods listed: GET, POST, PUT, DELETE, PATCH.
Place your cursor on the line you want to run to that entry and press `<leader>te` or run `HurlRunnerToEntry` command to execute the request.

[![Run to entry in split mode](https://i.gyazo.com/14d47adbfcab9e945f89e020b83328a9.gif)](https://gyazo.com/14d47adbfcab9e945f89e020b83328a9)

Note: it's running to that entry and ignore the remaining of the file. It is useful for debugging purposes.
Note: it's running from start of file to the selected entry and ignore the remaining of the file. It is useful for debugging purposes.

### Toggle Mode

Expand Down
17 changes: 16 additions & 1 deletion lua/hurl/health.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ local ok = vim.health.ok or vim.health.report_ok
local error = vim.health.error or vim.health.report_error

-- Add health check for default formatter: jq and prettier
function M.check()
M.check = function()
start('hurl.nvim health check')
local jq = vim.fn.executable('jq')
local prettier = vim.fn.executable('prettier')
Expand All @@ -22,6 +22,21 @@ function M.check()
ok('prettier found')
end

local ts
if xpcall(
function() ts = require("nvim-treesitter-language") end,
function(e) ts = e end)
then
ok('nvim-treesitter found')
if ts.language.get_lang('hurl') == 'hurl' then
ok(' hurl parser installed')
else
error(' hurl parser not found')
end
else
error('nvim-treesitter not found')
end

ok('hurl.nvim: All good!')
end

Expand Down
56 changes: 21 additions & 35 deletions lua/hurl/http_utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,46 +31,32 @@ local function find_http_verb(line, current_line_number)
end
end

--- Find the HTTP verbs in the current buffer
---@return table
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]
--- Find the closest HURL entry at the current cursor position.
local function find_hurl_entry_positions_in_buffer()
local ts = vim.treesitter
local node = ts.get_node()

local next_entry = 0
local current_index = 0
local current_verb = nil
local end_line = total_lines -- Default to the last line of the buffer

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, i)
if result then
next_entry = next_entry + 1
if i == current_line_number then
current_index = next_entry
current_verb = result
elseif current_verb and i > current_verb.line_number then
end_line = i - 1 -- The end line of the current verb is the line before the next verb starts
break -- No need to continue once the end line of the current verb is found
end
end
while node and node:type() ~= "entry" do
node = node:parent()
end

if current_verb and current_index == next_entry then
-- If the current verb is the last one, the end line is the last line of the buffer
end_line = total_lines
if not node then
return {
current = 0,
start_line = nil,
end_line = nil,
}
else
local r1, _, _ = node:start()
local r2, _, _ = node:end_()
return {
current = r1 + 1,
start_line = r1 + 1,
end_line = r2 + 1
}
end

return {
current = current_index,
start_line = current_verb and current_verb.line_number or nil,
end_line = end_line,
}
end

M.find_http_verb_positions_in_buffer = find_http_verb_positions_in_buffer
M.find_hurl_entry_positions_in_buffer = find_hurl_entry_positions_in_buffer

return M
6 changes: 3 additions & 3 deletions lua/hurl/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ function M.setup()

-- Run request at current line if there is a HTTP method
utils.create_cmd('HurlRunnerAt', function(opts)
local result = http.find_http_verb_positions_in_buffer()
local result = http.find_hurl_entry_positions_in_buffer()
if result.current > 0 and result.start_line and result.end_line then
utils.log_info(
'hurl: running request at line ' .. result.start_line .. ' to ' .. result.end_line
Expand All @@ -360,7 +360,7 @@ function M.setup()

-- Run request to current entry if there is a HTTP method
utils.create_cmd('HurlRunnerToEntry', function(opts)
local result = http.find_http_verb_positions_in_buffer()
local result = http.find_hurl_entry_positions_in_buffer()
if result.current > 0 then
opts.fargs = opts.fargs or {}
opts.fargs = vim.list_extend(opts.fargs, { '--to-entry', result.current })
Expand Down Expand Up @@ -390,7 +390,7 @@ function M.setup()
utils.create_cmd('HurlVerbose', function(opts)
-- It should be the same logic with run at current line but with verbose flag
-- The response will be sent to quickfix
local result = http.find_http_verb_positions_in_buffer()
local result = http.find_hurl_entry_positions_in_buffer()
if result.current > 0 and result.start_line and result.end_line then
utils.log_info(
'hurl: running request at line ' .. result.start_line .. ' to ' .. result.end_line
Expand Down

0 comments on commit 6a16d4f

Please sign in to comment.