feat: add Buffer:filter_cmd for ':%!cmd' behavior
All checks were successful
NeoVim tests / plenary-tests (push) Successful in 12s
All checks were successful
NeoVim tests / plenary-tests (push) Successful in 12s
This commit is contained in:
parent
1ba31a351d
commit
9992d5cd31
@ -78,4 +78,51 @@ end
|
|||||||
--- @param tree u.renderer.Tree
|
--- @param tree u.renderer.Tree
|
||||||
function Buffer:render(tree) return self.renderer:render(tree) end
|
function Buffer:render(tree) return self.renderer:render(tree) end
|
||||||
|
|
||||||
|
--- Filter buffer content through an external command (like Vim's :%!)
|
||||||
|
--- @param cmd string[] Command to run (with arguments)
|
||||||
|
--- @param opts? {cwd?: string, preserve_cursor?: boolean}
|
||||||
|
--- @return nil
|
||||||
|
--- @throws string Error message if command fails
|
||||||
|
--- @note Special placeholders in cmd:
|
||||||
|
--- - $FILE: replaced with the buffer's filename (if any)
|
||||||
|
--- - $DIR: replaced with the buffer's directory (if any)
|
||||||
|
function Buffer:filter_cmd(cmd, opts)
|
||||||
|
opts = opts or {}
|
||||||
|
local cwd = opts.cwd or vim.uv.cwd()
|
||||||
|
local old_lines = self:all():lines()
|
||||||
|
-- Save cursor position if needed, defaulting to true
|
||||||
|
local save_pos = opts.preserve_cursor ~= false and vim.fn.winsaveview()
|
||||||
|
|
||||||
|
-- Run the command
|
||||||
|
local result = vim
|
||||||
|
.system(
|
||||||
|
-- Replace special placeholders in `cmd` with their values:
|
||||||
|
vim
|
||||||
|
.iter(cmd)
|
||||||
|
:map(function(x)
|
||||||
|
if x == '$FILE' then return vim.api.nvim_buf_get_name(self.bufnr) end
|
||||||
|
if x == '$DIR' then return vim.fs.dirname(vim.api.nvim_buf_get_name(self.bufnr)) end
|
||||||
|
return x
|
||||||
|
end)
|
||||||
|
:totable(),
|
||||||
|
{
|
||||||
|
cwd = cwd,
|
||||||
|
stdin = old_lines,
|
||||||
|
text = true,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
:wait()
|
||||||
|
|
||||||
|
-- Check for command failure
|
||||||
|
if result.code ~= 0 then error('Command failed: ' .. (result.stderr or '')) end
|
||||||
|
|
||||||
|
-- Process and apply the result
|
||||||
|
local new_lines = vim.split(result.stdout, '\n')
|
||||||
|
if new_lines[#new_lines] == '' then table.remove(new_lines) end
|
||||||
|
Renderer.patch_lines(self.bufnr, old_lines, new_lines)
|
||||||
|
|
||||||
|
-- Restore cursor position if saved
|
||||||
|
if save_pos then vim.fn.winrestview(save_pos) end
|
||||||
|
end
|
||||||
|
|
||||||
return Buffer
|
return Buffer
|
||||||
|
Loading…
x
Reference in New Issue
Block a user