---Herdr CLI wrapper. All Herdr subprocess calls go through this module. ---@class HerdrSplitsHerdr local M = {} local config = require('herdr-splits.config') ---Resolve the herdr binary path. ---@return string function M.herdr_bin() return config.herdr_bin or vim.env.HERDR_BIN_PATH or 'herdr' end ---Check if Neovim is running inside a Herdr session. ---@return boolean function M.is_in_session() return vim.env.HERDR_ENV == '1' and vim.env.HERDR_PANE_ID ~= nil and #vim.env.HERDR_PANE_ID > 0 end ---Get the current Herdr pane ID. ---@return string|nil function M.current_pane_id() if not M.is_in_session() then return nil end return vim.env.HERDR_PANE_ID end ---Run a herdr CLI command and return stdout, stderr, and exit code. ---@param args string[] ---@return string stdout, string stderr, number exit_code local function herdr_exec(args) local cmd = vim.list_extend({ M.herdr_bin() }, args, 1, #args) local obj = vim.system(cmd, { text = true }):wait() return obj.stdout, obj.stderr, obj.code end ---Check if the current Herdr pane is at the layout boundary in the given direction. ---Calls `herdr pane edges --current` and parses the JSON response. ---@param direction '"left"'|'"right"'|'"up"'|'"down"' ---@return boolean|nil true if at edge, false if neighbor exists, nil on error function M.current_pane_at_edge(direction) if not M.is_in_session() then return nil end local edge_key = direction local stdout, _, code = herdr_exec({ 'pane', 'edges', '--current' }) if code ~= 0 or not stdout or #stdout == 0 then return nil end local ok, data = pcall(vim.json.decode, stdout) if not ok or type(data) ~= 'table' or type(data.result) ~= 'table' or type(data.result.edges) ~= 'table' then return nil end local at_edge = data.result.edges[edge_key] if type(at_edge) ~= 'boolean' then return nil end return at_edge end ---Check if the current Herdr pane is zoomed. ---Calls `herdr pane layout --current` and parses JSON. ---@return boolean|nil true if zoomed, false if not, nil on error function M.current_pane_is_zoomed() if not M.is_in_session() then return nil end local stdout, _, code = herdr_exec({ 'pane', 'layout', '--current' }) if code ~= 0 or not stdout or #stdout == 0 then return nil end local ok, data = pcall(vim.json.decode, stdout) if not ok or type(data) ~= 'table' or type(data.result) ~= 'table' or type(data.result.layout) ~= 'table' then return nil end local zoomed = data.result.layout.zoomed if type(zoomed) ~= 'boolean' then return nil end return zoomed end ---Focus a Herdr pane in the given direction. ---Calls `herdr pane focus --direction