celina

Search:
Group by:

Celina CLI Library

A powerful Terminal User Interface library for Nim, inspired by Ratatui. Provides high-performance, type-safe components for building interactive terminal applications with both synchronous and asynchronous support.

Basic Usage:

import pkg/celina

proc main() =
  var app = newApp()
  app.run()

when isMainModule:
  main()

Async Usage (requires Chronos and -d:asyncBackend=chronos):

import pkg/celina

proc main() {.async.} =
  var app = newAsyncApp()
  await app.runAsync()

when isMainModule:
  waitFor main()

Types

App = ref object
  ## Whether to use window management
  ## Current target FPS
  ## Frame counter for FPS calculation
  ## Last time FPS was calculated
  ## Cursor state management
AppConfig = object
  title*: string
  alternateScreen*: bool
  mouseCapture*: bool
  rawMode*: bool
  windowMode*: bool          ## Enable window management
  targetFps*: int            ## Target FPS for rendering (default: 60)

Procs

proc addWindow(app: App; window: Window): WindowId {....raises: [], tags: [],
    forbids: [].}
Add a window to the application
proc enableWindowMode(app: App) {....raises: [], tags: [], forbids: [].}
Enable window management mode
proc focusWindow(app: App; windowId: WindowId) {....raises: [], tags: [],
    forbids: [].}
Focus a specific window
proc getCurrentFps(app: App): float {....raises: [], tags: [TimeEffect],
                                      forbids: [].}
Get the current actual FPS based on frame counter
proc getCursorPos(app: App): (int, int) {....raises: [], tags: [], forbids: [].}
Get current cursor position
proc getCursorStyle(app: App): CursorStyle {....raises: [], tags: [], forbids: [].}
Get current cursor style
proc getFocusedWindow(app: App): Option[Window] {....raises: [], tags: [],
    forbids: [].}
Get the currently focused window
proc getFocusedWindowId(app: App): Option[WindowId] {....raises: [], tags: [],
    forbids: [].}
Get the ID of the currently focused window
proc getTargetFps(app: App): int {....raises: [], tags: [], forbids: [].}
Get the current target FPS
proc getWindow(app: App; windowId: WindowId): Option[Window] {....raises: [],
    tags: [], forbids: [].}
Get a window by ID
proc getWindowCount(app: App): int {....raises: [], tags: [], forbids: [].}
Get the total number of windows
proc getWindowInfo(app: App; windowId: WindowId): Option[WindowInfo] {.
    ...raises: [], tags: [], forbids: [].}
Get window information by ID
proc getWindows(app: App): seq[Window] {....raises: [], tags: [], forbids: [].}
Get all windows in the application
proc handleWindowEvent(app: App; event: Event): bool {....raises: [Exception],
    tags: [RootEffect], forbids: [].}
Handle an event through the window manager
proc hideCursor(app: App) {....raises: [], tags: [], forbids: [].}
Hide cursor in next render
proc isCursorVisible(app: App): bool {....raises: [], tags: [], forbids: [].}
Check if cursor is visible
proc newApp(config: AppConfig = AppConfig(title: "Celina App",
    alternateScreen: true, mouseCapture: false, rawMode: true,
    windowMode: false, targetFps: 60)): App {....raises: [], tags: [TimeEffect],
    forbids: [].}

Create a new CLI application with the specified configuration

Example:

let config = AppConfig(
  title: "My App",
  alternateScreen: true,
  mouseCapture: true
)
var app = newApp(config)

proc onEvent(app: App; handler: proc (event: Event): bool) {....raises: [],
    tags: [], forbids: [].}

Set the event handler for the application

The handler should return true if the event was handled, false if the application should quit.

Example:

app.onEvent proc(event: Event): bool =
  case event.kind
  of EventKind.Key:
    if event.key.code == KeyCode.Char and event.key.char == 'q':
      return false  # Quit application
    elif event.key.code == KeyCode.Escape:
      return false  # Quit on escape
  else:
    discard
  return true  # Continue running

proc onRender(app: App; handler: proc (buffer: var Buffer)) {....raises: [],
    tags: [], forbids: [].}

Set the render handler for the application

This handler is called each frame to update the display buffer.

Example:

app.onRender proc(buffer: var Buffer) =
  buffer.clear()
  let area = buffer.area
  let centerX = area.width div 2 - 5  # Center "Hello!"
  let centerY = area.height div 2
  buffer.setString(centerX, centerY, "Hello!", defaultStyle())

proc quickRun(eventHandler: proc (event: Event): bool;
              renderHandler: proc (buffer: var Buffer); config: AppConfig = AppConfig(
    title: "Celina App", alternateScreen: true, mouseCapture: false,
    rawMode: true, windowMode: false, targetFps: 60)) {.
    ...raises: [Exception, TerminalError:ObjectType, CatchableError],
    tags: [TimeEffect, WriteIOEffect, RootEffect, ReadIOEffect], forbids: [].}

Quick way to run a simple CLI application

Example:

quickRun(
  eventHandler = proc(event: Event): bool =
    case event.kind
    of EventKind.Key:
      if event.key.code == KeyCode.Char and event.key.char == 'q':
        return false
    else: discard
    return true,
  
  renderHandler = proc(buffer: var Buffer) =
    buffer.clear()
    let area = buffer.area
    buffer.setString(10, area.height div 2, "Press 'q' to quit", defaultStyle())
)

proc quit(app: App) {....raises: [], tags: [], forbids: [].}
Signal the application to quit gracefully
proc removeWindow(app: App; windowId: WindowId) {....raises: [], tags: [],
    forbids: [].}
Remove a window from the application
proc resetCursor(app: App) {....raises: [], tags: [], forbids: [].}
Reset cursor to default state (hidden, default style, position -1,-1)
proc run(app: App; config: AppConfig = AppConfig(title: "Celina App",
    alternateScreen: true, mouseCapture: false, rawMode: true,
    windowMode: false, targetFps: 60)) {.
    ...raises: [Exception, TerminalError:ObjectType, CatchableError],
    tags: [WriteIOEffect, RootEffect, ReadIOEffect], forbids: [].}

Run the application main loop

This will:

  1. Setup terminal state
  2. Enter main event loop
  3. Cleanup terminal state on exit

Example:

var app = newApp()

app.onEvent proc(event: Event): bool =
  # Handle events
  return true

app.onRender proc(buffer: var Buffer) =
  # Render UI
  buffer.drawString(0, 0, "Hello!", defaultStyle())

app.run()

proc setCursor(app: App; pos: Position) {....raises: [], tags: [], forbids: [].}
Set cursor position using Position type
proc setCursor(app: App; x, y: int) {....raises: [], tags: [], forbids: [].}
Set cursor position for next render Position will be applied after buffer rendering
proc setCursorPos(app: App; x, y: int) {....raises: [], tags: [], forbids: [].}
Set cursor position without affecting visibility state
proc setCursorStyle(app: App; style: CursorStyle) {....raises: [], tags: [],
    forbids: [].}
Set cursor style for next render
proc setTargetFps(app: App; fps: int) {....raises: [ValueError], tags: [],
                                        forbids: [].}
Set the target FPS for the application FPS must be between 1 and 120
proc showCursor(app: App) {....raises: [], tags: [], forbids: [].}
Show cursor in next render
proc version(): string {....raises: [], tags: [], forbids: [].}
Get the library version string

Exports

Position, size, position, isValid, contains, rect, size, shrink, isValid, contains, union, $, right, center, Area, $, Size, -, isEmpty, Rect, pos, area, area, expand, shrink, intersects, bottom, +, intersection, $, rect, indigo, color256, grayscale, toAnsiCode, ==, withModifiers, ColorKind, $, Style, $, deepSkyBlue, hotPink, toAnsiCode, bold, color256, reversed, hsv, Color, rgb, hsvToRgb, ColorValue, withBg, style, ==, withFg, brightColors, color, default, rgb, salmon, teal, addModifier, italic, violet, cubeColor, toAnsiSequence, RgbColor, crimson, limeGreen, withBg, $, style, ==, defaultColor, orange, lerp, underline, toAnsiCode, defaultStyle, withFg, darkColors, resetSequence, gold, toBgAnsiCode, lerp, StyleModifier, rgb, toAnsiCode, removeModifier, pastels, diff, clear, []=, isEmpty, isValidPos, fill, Buffer, ==, cell, Cell, ==, setString, merge, setRunes, isValidPos, setString, []=, $, $, [], runeWidth, runesWidth, width, cell, merge, newBuffer, cell, toStrings, setString, resize, setRunes, setString, newBuffer, [], readKeyInput, readKey, MouseEventKind, resizeDetected, KeyCode, KeyModifier, pollKey, waitForKey, initSignalHandling, waitForAnyKey, pollEvents, Event, checkResize, MouseButton, KeyEvent, MouseEvent, hasInput, EventKind, min, twoColumnPercent, withMargins, fill, percentage, Constraint, evenSplit, LayoutSolver, withMargin, Layout, length, layout, vertical, max, threeRow, twoColumn, ConstraintKind, $, split, Direction, ratio, horizontal, $, render, setCursorStyle, setupWithMouse, cleanup, enableRawMode, isRawMode, saveCursor, withTerminal, drawWithCursor, showCursor, disableAlternateScreen, getSize, clearToEndOfLine, clearLine, isAlternateScreen, clearScreen, TerminalError, updateSize, draw, restoreCursor, clearToStartOfLine, getTerminalSize, Terminal, withTerminal, moveCursorRight, moveCursorUp, moveCursorLeft, renderCell, disableMouse, setup, enableAlternateScreen, moveCursorDown, disableRawMode, setCursorPos, isMouseEnabled, renderFull, setCursorPos, hideCursor, getTerminalSizeOrDefault, enableMouse, newTerminal, setupWithHiddenCursor, getArea, moveCursor, WindowState, render, WindowEvent, render, setBorder, destroyWindowManager, defaultBorder, move, WindowKeyHandler, ==, getVisibleWindows, Window, defaultBorderChars, dispatchEvent, setKeyHandler, stopPropagation, WindowBorder, hide, $, removeWindow, getContentBuffer, WindowManager, bringToFront, handleEvent, focusWindow, destroyWindow, findWindowAt, addWindow, newWindow, getWindow, setResizeHandler, resize, restore, WindowInfo, sendToBack, setArea, setEventHandler, setTitle, EventHandler, WindowMouseHandler, maximize, show, dispatchResize, WindowId, preventDefault, clearEventHandlers, minimize, toWindowInfo, WindowEventHandler, handleWindowEvent, newWindowManager, BorderChars, setMouseHandler, getContentSize, getFocusedWindow, WindowResizeHandler, EventPhase, boldText, render, newText, text, Wrap, withWrap, getPreferredSize, Alignment, styledText, withStyle, Text, colorText, withAlignment, getMinSize, render, constrainSize, Widget, setState, updateState, measureWidget, getMinSize, canFocus, newWidget, renderStateful, getState, newStatefulWidget, renderWidgetAt, StatefulWidget, getPreferredSize, renderWidget, newTerminalError, formatError, recordError, ensure, withResource, chain, MemoryError, ensureNotNil, $, ErrorCode, withErrorContext, checkSystemCall, TerminalError, newIOError, debugAssert, newAsyncError, ValidationError, newSystemCallError, withNonBlocking, logError, globalErrorStats, SystemCallError, AsyncError, ErrorStats, clearErrorStats, CelinaIOError, withContext, getErrorReport, checkSystemCallVoid, newValidationError, newMemoryError, tryIO, CelinaError, tryRecover, retryOperation, checkForLeaks, getStats, ResourceId, ==, getGlobalResourceManager, acquire, newResourceGuard, initGlobalResourceManager, isValid, withManagedResource, newResourceManager, $, ResourceType, release, withResourceGuard, touchResource, globalResourceManager, release, ResourceState, getResourceInfo, getResourceStats, clear, ResourceGuard, cleanupAllResources, hash, ResourceManager, ResourceInfo, unregisterResource, get, newResourcePool, registerResource, cleanupLeakedResources, getAllResources, ResourcePool, asyncVersion, salmon, mergeAsync, AsyncAppError, setString, newWidget, WindowBorder, enableRawMode, waitForKeyAsync, cell, withAsyncBuffer, toBuffer, clear, newAsyncInputReader, AsyncBufferMetrics, hsvToRgb, renderAsync, drawAsync, newAsyncBuffer, setString, getTerminalSizeAsync, WindowId, ==, startAsync, disableRawMode, waitForMultipleEventsAsync, WindowEventHandler, ==, newBuffer, bottom, EventKind, onRenderAsync, hasChronos, waitForKey, $, violet, contains, getInputBufferStats, clearAsync, KeyCode, pollKeyAsync, lerp, AsyncAppConfig, pos, newAsyncWindowManager, setString, moveWindowAsync, $, cell, AsyncEventError, lerp, enableMouse, readCharAsync, KeyEvent, constrainSize, RgbColor, toBgAnsiCode, measureWidget, setCellAsync, getLastFrameTime, StyleModifier, rgb, getState, getMinSize, updateState, getAsyncBufferMetrics, clone, Wrap, writeStdoutAsync, withAlignment, setupWithMouseAsync, AsyncApp, deepSkyBlue, onEventAsync, destroyAsyncWindowManager, color256, resize, quitAsync, Size, AsyncTerminalError, ColorValue, checkResize, brightColors, fill, ColorKind, hideCursor, cleanupAsync, AsyncTerminal, renderAsync, hideCursorAsync, WindowKeyHandler, isRawMode, $, KeyModifier, ==, fillAsync, defaultColor, WindowState, $, initSignalHandling, right, showCursorAsync, MouseButton, clearScreenAsync, grayscale, ==, getSize, initAsyncEventSystem, hasInputAsync, getVisibleWindowsAsync, intersection, rgb, pollEventsAsync, withBg, stopAsync, resizeDetected, newAsyncBufferNoRM, updateFromBufferAsync, readKeyInput, sleepMs, width, toAnsiSequence, ==, asyncStdinFd, globalAsyncBufferMetrics, clearInputBuffer, writeEscapeAsync, italic, removeWindowAsync, pollKey, orange, addWindow, toAnsiCode, withFg, darkColors, center, resetSequence, isMouseEnabled, BorderChars, pastels, WindowResizeHandler, Position, bringToFrontAsync, render, getStats, shrink, newStatefulWidget, area, clearLine, hasAsyncDispatch, Window, reversed, getMinSize, AsyncBuffer, getWindowAsync, newAsyncBuffer, setStringAsync, canFocus, withAsyncTerminal, setString, runAsync, rgb, MouseEvent, color, WindowEvent, styledText, pollEvents, AsyncWindowError, isValid, AsyncInputReader, disableAlternateScreen, withBg, EventHandler, +, getCell, $, cell, parseMouseEventSGRAsync, setString, Rect, quickRunAsync, getCell, newAsyncEventStream, setString, AsyncIOError, getWindow, readKey, sendToBackAsync, withBufferAsync, AsyncBufferPool, enableWindowMode, focusWindowAsync, newAsyncBufferPool, newWindow, cleanupAsyncIO, moveCursorAsync, registerFD, isEmpty, toStringsAsync, diff, hasInput, merge, getFocusedWindowAsync, crimson, showCursor, style, handleEventAsync, waitForAnyKeyAsync, setCellAsync, peekCharAsync, boldText, []=, initAsyncIO, underline, getFrameCount, focusWindowAsync, $, withWrap, readKeyAsync, gold, [], intersects, StatefulWidget, [], $, diffAsync, withModifiers, addWindowAsync, toBufferAsync, getSize, trackAsyncBufferCreation, bold, hasDataAvailable, resizeDetected, Color, teal, renderCell, setRunes, enableAlternateScreen, $, setCursorPos, isEmpty, getArea, setStringAsync, renderWidgetAt, setState, rect, withBuffer, contains, newAsyncTerminal, destroyAsyncBufferPool, renderSync, Event, findWindowAtAsync, AsyncWindowManager, runesWidth, rect, setupAsync, updateFromBuffer, color256, parseMouseEventX10Async, toAnsiCode, getPreferredSize, default, withStyle, merge, isAlternateScreen, trackAsyncBufferDestroy, -, toAnsiCode, closeAsyncInputReader, withFg, resizeAsync, hsv, newText, isValidPos, asyncBackend, Buffer, disableMouse, resizeWindowAsync, Cell, area, drawAsync, newBuffer, withLock, unregisterFD, stats, MouseEventKind, $, text, cleanupAsyncEventSystem, newAsyncApp, size, clear, returnBuffer, readCharNonBlocking, setCursorPos, isValid, defaultStyle, getFocusedWindowAsync, getTerminalSize, newAsyncBufferNoRM, removeWindowAsync, toStrings, toAnsiCode, render, indigo, position, getWindowAsync, readNonBlocking, destroyAsync, runeWidth, AsyncEventStream, flushStdoutAsync, hotPink, updateSize, getWindow, readStdinAsync, Style, expand, style, isRunning, []=, addWindowAsync, isValidPos, renderFullAsync, shrink, setRunes, addModifier, getArea, cubeColor, Alignment, limeGreen, getPreferredSize, size, Widget, Text, clearScreen, Area, getBuffer, colorText, waitForAnyKey, WindowMouseHandler, testAsyncIO, renderStateful, union, hasAsyncSupport, checkResizeAsync, removeModifier, renderWidget, EventPhase, hasAsyncSupport, hasChronos, hasAsyncDispatch, CursorUpSeq, RenderBatch, ClearScreenSeq, AlternateScreenEnter, enableMouseMode, applyTerminalConfig, generateRenderBatch, CursorStyleBlinkingBlock, CursorStyleBlinkingUnderline, getRawModeConfig, ClearToEndOfLineSeq, CursorRightSeq, makeCursorPositionSeq, makeCursorPositionSeq, ClearToStartOfLineSeq, MouseSequences, disableMouseMode, AnsiSequence, ShowCursorSeq, buildDifferentialOutput, CursorStyleSteadyUnderline, AlternateScreenExit, MouseMode, getCursorStyleSeq, CursorStyleSteadyBlock, CursorStyle, RestoreCursorSeq, CursorLeftSeq, parseMouseEvent, isTerminalInteractive, calculateRenderMetrics, supportsAnsi, CursorState, buildFullRenderOutput, buildOutputWithCursor, RenderMetrics, RenderCommandKind, CursorStyleDefault, CursorStyleBlinkingBar, CursorDownSeq, makeCursorMoveSeq, optimizeRenderBatch, getTerminalSizeFromSystem, buildOutputString, SaveCursorSeq, getTerminalCapabilities, HideCursorSeq, addCommand, TerminalConfig, RenderCommand, getTerminalSizeWithFallback, CursorStyleSteadyBar, ClearLineSeq, calculateSimpleDiff