nvim + pi / bi-directional communication
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135local M = {}
local config = require('pi-nvim.config')local terminal = require('pi-nvim.cli.terminal')local source = require('pi-nvim.actions.source')local watch = require('pi-nvim.cli.watch')
--- Get plugin root directory (where lua/ lives)---@return stringlocal function get_plugin_root() local src = debug.getinfo(1, 'S').source:sub(2) -- Remove leading @ -- src is: /path/to/integrations/neovim/lua/pi-nvim/cli/init.lua -- We want: /path/to/integrations/neovim return vim.fn.fnamemodify(src, ':h:h:h:h')end
--- Check if nvim-pi is installed as a Pi package--- Parses `pi list` for npm or git installs of nvim-pi---@return boolean|nil true if found, false if not, nil if check failedlocal function is_installed_globally() local ok, out = pcall(vim.fn.system, { 'pi', 'list' }) if not ok or vim.v.shell_error ~= 0 then return nil end -- Match any pi list entry that resolves to nvim-pi (npm or git install) return out:match('npm:@aliou/nvim%-pi%s*$') ~= nil or out:match('git:github%.com/aliou/nvim%-pi%s*$') ~= nilend
--- Build Pi command with extension---@return string[]function M.build_cmd() local cfg = config.get()
local cmd = { 'pi' }
-- Determine whether to pass --extension. -- load_extension: true -> always pass --extension (default) -- load_extension: false -> never pass --extension -- load_extension: "auto" -> skip --extension if Pi has nvim-pi installed globally local load = cfg.load_extension if load == nil or load == true then local root = get_plugin_root() table.insert(cmd, '--extension') table.insert(cmd, root) elseif load == 'auto' then local installed = is_installed_globally() if not installed then local root = get_plugin_root() table.insert(cmd, '--extension') table.insert(cmd, root) end end
-- Optional CLI flags from config if cfg.models then table.insert(cmd, '--models') table.insert(cmd, cfg.models) end if cfg.provider then table.insert(cmd, '--provider') table.insert(cmd, cfg.provider) end if cfg.model then table.insert(cmd, '--model') table.insert(cmd, cfg.model) end if cfg.thinking then table.insert(cmd, '--thinking') table.insert(cmd, cfg.thinking) end
-- Extra args passthrough if cfg.extra_args then for _, arg in ipairs(cfg.extra_args) do table.insert(cmd, arg) end end
return cmdend
--- Open Pi terminalfunction M.open() -- Check if Pi is installed if vim.fn.executable('pi') ~= 1 then vim.notify('[pi-nvim] pi command not found', vim.log.levels.ERROR) return end
local term = terminal.get_current() if term then if not terminal.is_open(term) then terminal.show(term) else terminal.focus(term) end return end
-- Save current window as source before opening terminal source.save()
terminal.create(M.build_cmd()) watch.enable()end
--- Close Pi terminal (kills process)function M.close() local term = terminal.get_current() if term then terminal.close(term) watch.disable() endend
--- Toggle Pi terminalfunction M.toggle() local term = terminal.get_current() if term and terminal.is_open(term) then M.close() else M.open() endend
--- Check if Pi terminal is open---@return booleanfunction M.is_open() local term = terminal.get_current() return term ~= nil and terminal.is_open(term)end
return M