textview

package
v0.17.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package textview is a read-only viewer for static text content, wrapped in a pane. Reach for it when the payload is a rendered document — a README, a diff, a kubectl describe, a PR body — where logview's streaming shape (append / follow / filter mode / MaxLines trim) is noise. textview drops all of that and keeps the machinery that read- static-text actually needs: scroll, search, wrap.

The body is a pkg/pane.Pane (so ↑↓/j/k/PgUp/PgDn scrolling work out of the box), plus an optional pkg/filter.Model for the "/-to-search" overlay. Content is replaced wholesale via SetContent; there is no Append or Clear — see pkg/logview for the streaming case.

Behavior:

  • SetContent replaces the buffer and resets scroll to the top.
  • Wrap is on by default: long lines wrap to the pane's inner width (ANSI-aware via x/ansi.Wrap). Toggle at runtime with `w`. Wrap-off mode falls back to pane's own truncation + horizontal scroll (rule 16).
  • "/" focuses an embedded filter input; typing highlights case- insensitive substring matches inline; enter blurs (keeps the query active for n/N); esc clears.
  • n / N step to the next / previous match.
  • g / G jump to top / bottom (rule 23: no `gg` — single g means top library-wide).
  • ctrl+u / ctrl+d half-page; pgup / pgdown full-page.
  • No filter mode. No follow. No MaxLines. If you want streaming + filter drop + tail-mode, use pkg/logview.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Keys

type Keys struct {
	Search, NextMatch, PrevMatch key.Binding
	Top, Bottom                  key.Binding
	Wrap                         key.Binding
	Pane                         pane.Keys
}

Keys is the textview's keymap. Each binding carries both its dispatch keys (WithKeys) and its help label (WithHelp) — Update and Help() read from the same struct, so a custom binding propagates everywhere. Pane covers horizontal scroll and pgup/pgdn/half-page; textview owns the search + wrap-toggle bindings.

func DefaultKeys

func DefaultKeys() Keys

DefaultKeys returns the textview's stock keymap.

type Model

type Model struct {
	// contains filtered or unexported fields
}

Model is the textview widget. Embed by value; mutate via the setters.

func New

func New(opts Options) Model

New constructs a textview.

func (Model) Content

func (m Model) Content() string

Content returns the raw text (pre-wrap) currently loaded.

func (Model) Help

func (m Model) Help() []key.Binding

Help returns the keys this textview responds to. While the embedded filter is focused, returns the filter's keys; otherwise the navigation + search + wrap bindings appropriate for the current state.

func (Model) Init

func (m Model) Init() tea.Cmd

Init satisfies tea.Model.

func (Model) Loading

func (m Model) Loading() bool

Loading reports whether the textview is currently in its loading state.

func (Model) Query

func (m Model) Query() string

Query returns the current search text ("" when no search is active).

func (Model) Searching

func (m Model) Searching() bool

Searching reports whether the embedded filter currently has focus. Mirror this from the enclosing screen's IsCapturingKeys() so the app shell keeps its global keys (q, t, esc) out of the search input.

func (*Model) SetActiveColor

func (m *Model) SetActiveColor(c lipgloss.TerminalColor)

SetActiveColor updates the body pane's active border color.

func (*Model) SetContent

func (m *Model) SetContent(s string)

SetContent replaces the buffer and resets scroll to the top. Any active search query is preserved; matches are recomputed against the new content and the current match resets to the first hit.

func (*Model) SetCurrentLineStyle

func (m *Model) SetCurrentLineStyle(s lipgloss.Style)

SetCurrentLineStyle updates the style applied to the line holding the current match.

func (*Model) SetDimensions

func (m *Model) SetDimensions(w, h int)

SetDimensions resizes the textview in place. When searchable, the filter takes 3 rows at the top and the body pane gets the rest.

func (*Model) SetFocused

func (m *Model) SetFocused(b bool)

SetFocused flips the body pane's focus state.

func (*Model) SetInactiveColor

func (m *Model) SetInactiveColor(c lipgloss.TerminalColor)

SetInactiveColor updates the body pane's inactive border color.

func (*Model) SetLoading

func (m *Model) SetLoading(b bool) tea.Cmd

SetLoading toggles the loading state. When entering, returns the spinner's initial Tick command — propagate it back from your screen's Update so the spinner animates.

func (*Model) SetLoadingLabel

func (m *Model) SetLoadingLabel(s string)

SetLoadingLabel updates the text rendered next to the spinner while loading.

func (*Model) SetMatchStyle

func (m *Model) SetMatchStyle(s lipgloss.Style)

SetMatchStyle updates the highlight style applied to matched substrings.

func (*Model) SetQuery

func (m *Model) SetQuery(s string)

SetQuery sets the search text programmatically (no-op when not Searchable).

func (*Model) SetSpinnerStyle

func (m *Model) SetSpinnerStyle(s lipgloss.Style)

SetSpinnerStyle updates the lipgloss style applied to the spinner glyph.

func (*Model) SetTitle

func (m *Model) SetTitle(s string)

SetTitle sets the pane's top-left title.

func (*Model) SetWrap

func (m *Model) SetWrap(b bool)

SetWrap flips wrap on or off. When enabled, content re-wraps to the pane's inner width; when disabled, pane's own horizontal scroll takes over.

func (Model) Update

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd)

Update dispatches search, match jumping, top/bottom jumps, wrap toggle, and forwards everything else to the body pane.

func (Model) View

func (m Model) View() string

View stacks the filter (when searchable) above the body pane.

func (Model) Wrap

func (m Model) Wrap() bool

Wrap reports whether word-wrap is currently enabled.

type Options

type Options struct {
	Width, Height int
	// Title sits on the pane's top-left border slot. Defaults to "text".
	Title string
	// Content is the initial body text. Replace at runtime via SetContent.
	Content string
	// Wrap enables word-wrapping to the pane's inner width. Default is
	// true; when false the pane's built-in truncation + horizontal scroll
	// handles overflow (rule 16).
	Wrap bool
	// Searchable embeds a filter.Model above the body pane (three rows).
	// When false, "/" is ignored and the full height is used for content.
	Searchable bool

	// MatchStyle is the lipgloss style applied to matched substrings while
	// a query is active. Pass via theme.TextView() for a sensible default.
	MatchStyle lipgloss.Style

	// CurrentLineStyle is applied to the entire line holding the current
	// match, padded to the pane's inner width so a Background paints the
	// whole row. Zero value leaves the row unstyled.
	CurrentLineStyle lipgloss.Style

	// Pane pass-throughs. See pkg/pane.Options for defaults.
	ActiveColor    lipgloss.TerminalColor
	InactiveColor  lipgloss.TerminalColor
	ActiveBorder   lipgloss.Border
	InactiveBorder lipgloss.Border
	SlotBrackets   pane.SlotBracketStyle

	// SpinnerStyle is applied to the spinner glyph rendered while the
	// textview is in its loading state (see SetLoading).
	SpinnerStyle lipgloss.Style
	// LoadingLabel is rendered next to the spinner while loading.
	LoadingLabel string

	// Filter configures the embedded filter. Ignored when Searchable=false.
	Filter filter.Options

	// Keys is the textview's keymap. Leave zero to use DefaultKeys.
	Keys Keys
}

Options configures a new textview. Zero-value fields fall back to defaults; start from theme.TextView() to fill in the color tokens.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL