Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,9 @@ Boolean value. If `true`, will run `=` operator on new buffer text. Requires

#### `target`

TSNode. If present, this node will be used as the target for replacement instead
TSNode or list of TSNodes. If present, this node will be used as the target for replacement instead
of the node under your cursor.
If list of nodes their combined range will be used for replacement. Note that in this case if the target nodes specified are not next to each other, any thing in between will also be replaced.

Here's a simplified example of how a node-action function gets called:

Expand Down
35 changes: 33 additions & 2 deletions lua/ts-node-action/init.lua
Original file line number Diff line number Diff line change
@@ -1,15 +1,46 @@
local M = {}

--- @private
--- @param targets TSNode[]
--- @return integer start_row
--- @return integer start_col
--- @return integer end_row
--- @return integer end_col
local function combined_range(targets)
local start_row, start_col, end_row, end_col
for _, target in ipairs(targets) do
local sr, sc, er, ec = target:range()
if start_row == nil or sr < start_row then
start_row = sr
end
if start_col == nil or sc < start_col then
start_col = sc
end
if end_row == nil or er > end_row then
end_row = er
end
if end_col == nil or ec > end_col then
end_col = ec
end
end
return start_row, start_col, end_row, end_col
end

--- @private
--- @param replacement string|table
--- @param opts { cursor: { col: number, row: number }, callback: function, format: boolean, target: TSNode }
--- @param opts { cursor: { col: number, row: number }, callback: function, format: boolean, target: TSNode | TSNode[] }
--- All opts fields are optional
local function replace_node(node, replacement, opts)
if type(replacement) ~= "table" then
replacement = { replacement }
end

local start_row, start_col, end_row, end_col = (opts.target or node):range()
local start_row, start_col, end_row, end_col
if vim.islist(opts.target) then
start_row, start_col, end_row, end_col = combined_range(opts.target)
else
start_row, start_col, end_row, end_col = (opts.target or node):range()
end
vim.api.nvim_buf_set_text(
vim.api.nvim_get_current_buf(),
start_row,
Expand Down