// ============================================================================ // SVELTUI - CURSOR MODULE // Controls native terminal cursor visibility and style // // Note: Native cursor COLOR cannot be controlled via ANSI - that's set by // the terminal emulator. For custom colored cursors, use the component. // // Usage: // import { cursor } from 'sveltui' // cursor.hide() // cursor.show() // cursor.setStyle('bar') // ============================================================================ import { writeStdout } from '../utils/bun-output.ts' import * as ANSI from '../utils/ansi-codes.ts' // ============================================================================ // TYPES // ============================================================================ export type CursorStyle = 'block' | 'underline' | 'bar' | 'default' export type CursorVisibility = 'visible' | 'hidden' export interface CursorOptions { /** Initial visibility - 'visible' or 'hidden' */ visibility?: CursorVisibility /** Cursor style - 'block', 'underline', 'bar', or 'default' */ style?: CursorStyle /** Whether cursor blinks (terminal native blink) */ blink?: boolean } // ============================================================================ // STATE // ============================================================================ let _visible = true let _style: CursorStyle = 'default' let _blink = true // ============================================================================ // STYLE MAPPING // ============================================================================ function getStyleCode(style: CursorStyle, blink: boolean): string { switch (style) { case 'block': return blink ? ANSI.CURSOR_BLOCK_BLINK : ANSI.CURSOR_BLOCK case 'underline': return blink ? ANSI.CURSOR_UNDERLINE_BLINK : ANSI.CURSOR_UNDERLINE case 'bar': return blink ? ANSI.CURSOR_BAR_BLINK : ANSI.CURSOR_BAR case 'default': default: return ANSI.CURSOR_DEFAULT } } // ============================================================================ // PUBLIC API // ============================================================================ /** * Hide the native terminal cursor */ export function hide(): void { _visible = false writeStdout(ANSI.HIDE_CURSOR) } /** * Show the native terminal cursor */ export function show(): void { _visible = true writeStdout(ANSI.SHOW_CURSOR) } /** * Toggle cursor visibility */ export function toggle(): void { if (_visible) { hide() } else { show() } } /** * Set cursor style (block, underline, bar, or default) */ export function setStyle(style: CursorStyle): void { _style = style writeStdout(getStyleCode(_style, _blink)) } /** * Set cursor blink on/off */ export function setBlink(blink: boolean): void { _blink = blink writeStdout(getStyleCode(_style, _blink)) } /** * Configure cursor with multiple options at once */ export function configure(options: CursorOptions): void { if (options.style !== undefined) { _style = options.style } if (options.blink !== undefined) { _blink = options.blink } if (options.visibility !== undefined) { _visible = options.visibility === 'visible' } // Apply style first, then visibility writeStdout(getStyleCode(_style, _blink)) writeStdout(_visible ? ANSI.SHOW_CURSOR : ANSI.HIDE_CURSOR) } /** * Reset cursor to default terminal style and show it */ export function reset(): void { _style = 'default' _blink = true _visible = true writeStdout(ANSI.CURSOR_DEFAULT) writeStdout(ANSI.SHOW_CURSOR) } /** * Get current cursor state (for debugging/introspection) */ export function getState(): { visible: boolean; style: CursorStyle; blink: boolean } { return { visible: _visible, style: _style, blink: _blink, } } // ============================================================================ // EXPORT AS OBJECT (cursor.hide(), cursor.show(), etc.) // ============================================================================ export const cursor = { hide, show, toggle, setStyle, setBlink, configure, reset, getState, // Getters for current state get visible() { return _visible }, get style() { return _style }, get blink() { return _blink }, }