Selkie--Widget--TextStream

NAME

Selkie::Widget::TextStream - Append-only log with ring buffer and auto-scroll

SYNOPSIS

use Selkie::Widget::TextStream;
use Selkie::Sizing;

my $log = Selkie::Widget::TextStream.new(
    sizing    => Sizing.flex,
    max-lines => 10_000,
);

$log.append('Starting up...');
$log.append('Connected', style => Selkie::Style.new(fg => 0x9ECE6A));

# Or drive from a Supply — each emission becomes a line
$log.start-supply($lines-from-somewhere);

DESCRIPTION

A scrollable log of text lines. Internally a ring buffer — bounded by max-lines — so it's safe to append from high-volume sources without unbounded memory growth.

Auto-scrolls to the bottom on append while the user is "at the end" (the default state). When the user scrolls up with arrow keys or the mouse wheel, auto-scroll pauses until they scroll back to the bottom.

Arrow keys, Page Up/Down, Home/End, and the scroll wheel are handled when the widget is focused.

EXAMPLES

A streaming chat view

Pipe every message in a store-held array into the stream:

$app.store.subscribe-with-callback(
    'message-log',
    -> $s { $s.get-in('messages') // [] },
    -> @msgs { $log.clear; $log.append(.<text>) for @msgs },
    $log,
);

Colour-coded log levels

$log.append("INFO  $line", style => Selkie::Style.new(fg => 0xC0C0C0));
$log.append("WARN  $line", style => Selkie::Style.new(fg => 0xFFCC00));
$log.append("ERROR $line", style => Selkie::Style.new(fg => 0xFF5555, bold => True));

SEE ALSO

has UInt $.max-lines

Maximum number of lines retained. Older lines are discarded as new ones arrive (ring buffer). Defaults to 10,000.

has Bool $.show-scrollbar

Whether to render the vertical scrollbar on the right edge when the buffer is taller than the viewport.

method logical-height

method logical-height() returns UInt

Number of lines currently in the buffer.

method supply

method supply() returns Supply

Tap this to get every line as it's appended. Useful for mirroring output to an external sink (log file, network).

method start-supply

method start-supply(
    Supply $s
) returns Mu

Forward every value from a Supply into the stream, coerced to string and split on newlines. Convenience for piping LLM streams, subprocess output, etc.

method append

method append(
    Str:D $text,
    Selkie::Style :$style
) returns Mu

Append text. If the text contains newlines, each line becomes a separate buffer entry. The optional :style decorates those lines without affecting the rest of the buffer.

method scroll-to

method scroll-to(
    Int $row where { ... }
) returns Mu

Scroll to a specific row (0 = top). Above the max offset is clamped. Auto-follow is re-enabled when you scroll to the end.

method scroll-by

method scroll-by(
    Int $delta
) returns Mu

Scroll by a relative delta. Negative goes up, positive goes down.

method scroll-to-start

method scroll-to-start() returns Mu

Jump to the top of the buffer. Disables auto-follow until the user scrolls back to the end.

method scroll-to-end

method scroll-to-end() returns Mu

Jump to the bottom and re-enable auto-follow.

method clear

method clear() returns Mu

Empty the buffer and reset to the top.

method render-region

method render-region(
    Int :$offset where { ... },
    Int :$height where { ... }
) returns Mu

Region-render hook for compatibility with ScrollView's viewport protocol. TextStream manages its own scroll offset and renders its full visible region in render, so the :offset / :height arguments are accepted but ignored — pass-through to render.

Selkie v0.10.0

High-level TUI framework built on Notcurses

Authors

  • Matt Doughty

License

Artistic-2.0

Dependencies

Notcurses::Native:ver<0.4.0+>:auth<zef:apogee>

Test Dependencies

Provides

  • Selkie
  • Selkie::App
  • Selkie::App::Internal::Dispatch
  • Selkie::App::Internal::ErrorLog
  • Selkie::App::Internal::FocusTree
  • Selkie::App::Internal::HitTest
  • Selkie::App::Internal::IdleBudget
  • Selkie::App::Internal::OverlayTree
  • Selkie::App::Internal::RenderLoop
  • Selkie::App::Internal::ScreenModalLifecycle
  • Selkie::App::Internal::Terminal
  • Selkie::App::Internal::TerminalSequences
  • Selkie::Container
  • Selkie::EffectiveBounds
  • Selkie::Event
  • Selkie::Layout::Allocate
  • Selkie::Layout::HBox
  • Selkie::Layout::Split
  • Selkie::Layout::VBox
  • Selkie::Plot::Palette
  • Selkie::Plot::Scaler
  • Selkie::Plot::Ticks
  • Selkie::ScreenManager
  • Selkie::Sizing
  • Selkie::Store
  • Selkie::Style
  • Selkie::Test::Focus
  • Selkie::Test::Keys
  • Selkie::Test::Snapshot
  • Selkie::Test::Snapshot::Harness
  • Selkie::Test::Store
  • Selkie::Test::Supply
  • Selkie::Test::Tree
  • Selkie::Theme
  • Selkie::Trace
  • Selkie::Tree
  • Selkie::Widget
  • Selkie::Widget::Axis
  • Selkie::Widget::BarChart
  • Selkie::Widget::Border
  • Selkie::Widget::Button
  • Selkie::Widget::CardList
  • Selkie::Widget::Checkbox
  • Selkie::Widget::CommandPalette
  • Selkie::Widget::ConfirmModal
  • Selkie::Widget::FileBrowser
  • Selkie::Widget::FocusableByDefault
  • Selkie::Widget::Heatmap
  • Selkie::Widget::HelpOverlay
  • Selkie::Widget::Histogram
  • Selkie::Widget::Image
  • Selkie::Widget::Legend
  • Selkie::Widget::LineChart
  • Selkie::Widget::ListView
  • Selkie::Widget::Modal
  • Selkie::Widget::MultiLineInput
  • Selkie::Widget::PasswordStrength
  • Selkie::Widget::Plot
  • Selkie::Widget::ProgressBar
  • Selkie::Widget::RadioGroup
  • Selkie::Widget::RichText
  • Selkie::Widget::RichText::Span
  • Selkie::Widget::ScatterPlot
  • Selkie::Widget::ScrollView
  • Selkie::Widget::Select
  • Selkie::Widget::Sparkline
  • Selkie::Widget::Spinner
  • Selkie::Widget::TabBar
  • Selkie::Widget::Table
  • Selkie::Widget::Text
  • Selkie::Widget::TextInput
  • Selkie::Widget::TextInput::HighlightSpan
  • Selkie::Widget::TextStream
  • Selkie::Widget::Toast
  • Selkie::Widget::ViewportedCardList

Documentation

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.