import type { RpcClient } from "@neoinkjs/rpc"; import type { Nvim } from "./index"; import { subscribeNotification } from "./notify"; /** * The RPC method name the `VimResized` autocmd fires via `rpcnotify`, and the * method the host filters for. Single source of truth so the autocmd command * and the subscriber (`render.ts`) can never drift apart — mirrors * `NEOINK_INPUT_METHOD` in `input.ts`. */ export const NEOINK_RESIZE_METHOD = "neoink_resize"; /** * The Ex command a `VimResized` autocmd runs: notifies the host with the * NEW width. `&columns` is read at the moment the autocmd fires — i.e. * already the post-resize value — so the host never needs a follow-up * request to learn the new width; it arrives as the notification's only * argument. */ function buildAutocmdCommand(channelId: number): string { return `call rpcnotify(${channelId}, '${NEOINK_RESIZE_METHOD}', &columns)`; } /** * Registers the `VimResized` autocmd that reports terminal/UI width changes * to the host — Ink parity: Ink listens for its stdout's `'resize'` event; * neoink has no such stream, so it listens for Neovim's own resize signal * instead. Returns the autocmd id, which `uninstallResizeAutocmd` accepts to * tear it back down (`render.ts` does this on unmount). */ export async function installResizeAutocmd(nvim: Nvim, channelId: number): Promise { return nvim.createAutocmd("VimResized", buildAutocmdCommand(channelId)); } /** Removes a resize autocmd previously installed by `installResizeAutocmd`. */ export async function uninstallResizeAutocmd(nvim: Nvim, autocmdId: number): Promise { await nvim.deleteAutocmd(autocmdId); } /** * Routes `neoink_resize` notifications on `client` to `handler` with just the * new width. Returns an unsubscribe function. Mirrors `subscribeInput`. */ export function subscribeResize(client: RpcClient, handler: (columns: number) => void): () => void { return subscribeNotification( client, NEOINK_RESIZE_METHOD, (value): value is number => typeof value === "number", handler, ); }