repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
neovim/lua/bugabinga/pivi/bridge.lua
Rawlocal edit = require 'bugabinga.pivi.edit'
local context = require 'bugabinga.pivi.context'
local activity = require 'bugabinga.pivi.activity'
local docs = require 'bugabinga.pivi.docs'
local failure = function( message )
return { ok = false, error = tostring( message ), }
end
local ensure_buffer = function( path )
local bufnr = edit.buffer_for( path )
if bufnr then return bufnr, true end
return nil, false
end
local actions = {}
--- Loaded buffers, including unsaved content, win over disk.
actions.read = function( request )
if type( request.path ) ~= 'string' then return failure 'path is required' end
local content, source = edit.read( request.path )
if content == nil then return failure( 'cannot read ' .. request.path ) end
return { ok = true, content = content, source = source, }
end
actions.write = function( request )
if type( request.path ) ~= 'string' then return failure 'path is required' end
if type( request.content ) ~= 'string' then return failure 'content is required' end
local bufnr = ensure_buffer( request.path )
if not bufnr then
local ok, problem = pcall( vim.fn.writefile, vim.split( request.content, '\n', { plain = true, } ), request.path )
if not ok then return failure( problem ) end
return { ok = true, source = 'disk', }
end
local applied, joined = edit.set_content( bufnr, request.content )
if not applied then return failure 'buffer write failed' end
local persisted = edit.persist( bufnr )
return { ok = true, source = 'buffer', joined = joined, persisted = persisted, }
end
actions.edit = function( request )
if type( request.path ) ~= 'string' then return failure 'path is required' end
if type( request.old_text ) ~= 'string' then return failure 'old_text is required' end
if type( request.new_text ) ~= 'string' then return failure 'new_text is required' end
local bufnr = ensure_buffer( request.path )
if not bufnr then
local content = edit.read( request.path )
if content == nil then return failure( 'cannot read ' .. request.path ) end
local first = content:find( request.old_text, 1, true )
if not first then return failure 'old_text not found' end
local replaced = content:sub( 1, first - 1 ) .. request.new_text .. content:sub( first + #request.old_text )
local ok, problem = pcall( vim.fn.writefile, vim.split( replaced, '\n', { plain = true, } ), request.path )
if not ok then return failure( problem ) end
return { ok = true, source = 'disk', }
end
local applied, problem = edit.replace( bufnr, request.old_text, request.new_text )
if not applied then return failure( problem ) end
local persisted = edit.persist( bufnr )
return { ok = true, source = 'buffer', joined = problem, persisted = persisted, }
end
actions.state = function()
return { ok = true, state = context.editor(), }
end
actions.view = function()
return { ok = true, view = context.visible(), }
end
--- Resolves help exactly as this Neovim would, plugin documentation included.
actions.help = function( request )
if type( request.tag ) ~= 'string' or request.tag == '' then return failure 'tag is required' end
local result = docs.read( request.tag )
if not result.found then
return { ok = true, found = false, tag = result.tag, candidates = result.candidates, }
end
return {
ok = true,
found = true,
tag = result.tag,
file = result.file,
path = result.path,
line = result.line,
text = result.text,
}
end
actions.lua = function( request )
if type( request.code ) ~= 'string' then return failure 'code is required' end
local chunk, problem = loadstring( request.code, 'pivi' )
if not chunk then return failure( problem ) end
local ok, result = pcall( chunk )
if not ok then return failure( result ) end
return { ok = true, result = vim.inspect( result ), }
end
actions.findings = function( request )
local entries = activity.findings( request.items, request.title )
return { ok = true, count = #entries, }
end
actions.diagnostics = function( request )
if type( request.path ) ~= 'string' then return failure 'path is required' end
local bufnr = ensure_buffer( request.path )
if not bufnr then return failure 'file is not loaded in a buffer' end
activity.diagnose( bufnr, request.items )
return { ok = true, count = #( request.items or {} ), }
end
--- Single entry point used by the companion Pi extension.
--- @param request table action plus action specific fields
local handle = function( request )
if type( request ) ~= 'table' then return failure 'request must be a table' end
local action = actions[request.action]
if not action then return failure( 'unknown action: ' .. tostring( request.action ) ) end
local ok, result = pcall( action, request )
if not ok then return failure( result ) end
return result
end
return {
handle = handle,
actions = actions,
}