Skip to content

Commit

Permalink
refactor(send.lua): enhance pipeline handling to rely only on treesitter
Browse files Browse the repository at this point in the history
  • Loading branch information
PMassicotte committed Feb 23, 2025
1 parent ae2e38b commit 36049bd
Showing 1 changed file with 82 additions and 10 deletions.
92 changes: 82 additions & 10 deletions lua/r/send.lua
Original file line number Diff line number Diff line change
Expand Up @@ -645,22 +645,94 @@ M.line = function(m)
end
end

-- Function to check if a string ends with a specific suffix
---@param str string
---@param suffix string
---@return boolean
local function ends_with(str, suffix) return str:sub(-#suffix) == suffix end
M.chain = function()
local bufnr = create_r_buffer()
if not bufnr then return end

local function trim_lines(array)
local result = {} -- Create a new table to store the trimmed lines

for i = 1, #array do
local line = array[i]
local trimmedLine = line:match("^%s*(.-)%s*$") -- Remove leading and trailing whitespace
table.insert(result, trimmedLine) -- Add the trimmed line to the result table
local tree = parser:parse()[1]
if not tree then return end

local root = tree:root()
local query = vim.treesitter.query.parse(
"r",
[[
(_
(binary_operator
lhs: (_)
operator: ([("|>") ("<-") ("+") ("special")])
rhs: (call)
) @pipeline_no_assign
(#not-has-parent? @pipeline_no_assign binary_operator)
)
(_
; Handle when the pipeline is assignment to a variable
(binary_operator
lhs: (identifier)
rhs: (binary_operator
lhs: (_)
operator: ([("|>") ("+") ("special")])
rhs: (call)
) @pipeline_with_assign
)
)
]]
)

local cursor_row = vim.api.nvim_win_get_cursor(0)[1] - 1
local pipe_block_node

for _, node in query:iter_captures(root, bufnr, 0, -1) do
local start_row, _, end_row = node:range()
if cursor_row >= start_row and cursor_row <= end_row then
pipe_block_node = node
break
end
end

if not pipe_block_node then
inform("The cursor is not inside a piped expression.")
return
end

return result
local call_query = vim.treesitter.query.parse(
"r",
[[
(_
(binary_operator
lhs: (_)
operator: (["|>" "+" "special"] @operator)
rhs: (call) @call
(#not-has-ancestor? @call call) ;; Ensure the rhs is not inside another call
)
)
]]
)

local sibling = nil
local visited = false

for id, node, _ in call_query:iter_captures(pipe_block_node, bufnr, 0, -1) do
local capture_name = call_query.captures[id]
local start_row, _, end_row = node:range()

if
capture_name == "operator" and visited
or cursor_row == pipe_block_node:range()
then
sibling = node:prev_sibling()
break
elseif capture_name == "call" then
if cursor_row >= start_row and cursor_row <= end_row then visited = true end
end
end

local captured_node = sibling or pipe_block_node

M.source_lines({ vim.treesitter.get_node_text(captured_node, bufnr) }, nil)
end

-- Remove the <-, |>/%>% or + from the text
Expand Down

0 comments on commit 36049bd

Please sign in to comment.