treeview

package module
v1.8.2 Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2025 License: GPL-3.0 Imports: 17 Imported by: 1

README

TreeView

TreeView is a feature-rich Go library for displaying and navigating tree structures in the terminal. TreeView has full Bubble Tea and Lipgloss support, allowing you to build glamorous, interactive terminal applications.

Why TreeView?

What sets TreeView apart is its flexibility. You can build trees from any data source: flat lists with parent relationships, pre-nested hierarchical data, or create trees from your filesystem. The search and filtering system uses customizable predicates, giving you complete control over how users find what they're looking for. Search results automatically expand ancestor nodes so matches are visible, and the real-time filtering keeps the tree structure intact while hiding irrelevant items. When dealing with large trees, the bubbletea viewport support ensures smooth scrolling and focus. Navigation feels natural with keyboard bindings that you can customize to match your app's needs.

The styling system is particularly powerful. TreeView automatically detects file types and applies appropriate icons, but you can customize everything through the provider system to style any hierarchical with glamor. Whether you want subtle themes or vibrant, emoji-heavy displays, the Lipgloss integration makes it straightforward.

TreeView is ready for production. It provides proper error handling with sentinel errors, operations respect context cancellation and timeouts, and the library is thread-safe where it matters.


Examples

The examples directory contains twelve progressively complex demonstrations, from basic tree rendering to a fully-featured file browser. Each example includes comments and animated demos, so you can see exactly how to implement specific features in your own applications.

Basic Examples

Basic examples only demonstrate building and rendering a tree in the console.

Simple Tree
This example demonstrates the fundamental tree creation and rendering capabilities of the TreeView library.

Demo

Iterators
This example demonstrates how to range over a tree's nodes using the provided iterators.

Demo

Custom Styling
A showcase of the styling capabilities provided via lipgloss support

Demo

Comparison Display
This example demonstrates visualizing comparison operations with before and after displays.

Demo

Workflow Visualization
Example showing how to create domain-specific tree nodes for process and workflow tracking.

Demo

Build Trees From Parent Relationships
Shows how to use BuildTree to create trees from flat data structures where relationships are defined by parent ID references.

Demo

Build Trees From Hierarchical Data
Demonstrates using BuildTree for constructing trees from naturally hierarchical data structures.

Demo

Filesystem Builder
Demonstrates creating filesystem tree structures with NewTreeFromFileSystem constructor with support for special path characters like ., .., and ~. Shows path resolution, configurable depth limits, hidden file handling, and automatic file type detection for styling.

Demo
Intermediate Examples

Intermediate examples demonstrate treeview's full TUI support via BubbleTea.

Keyboard Controls
Advanced interactive example demonstrating comprehensive keyboard-based navigation within tree structures. Shows how to implement arrow key navigation, selection management, and basic searching.

Demo

Search & Filtering
This example demonstrates extending the search functionality to handle domain data.

Demo

Viewport Rendering
Demonstrates viewport-aware rendering for handling large tree structures. Solves the common problem of cursor navigation going off-screen in large directory trees by implementing automatic scrolling and responsive viewport management.

Demo

File Browser
Complete, terminal file browser application built with TreeView and Bubble Tea.

Demo

Contributing

Contributions are welcome! If you have any suggestions or encounter a bug, please open an issue or submit a pull request.

When contributing:

  1. Fork the repository and create a new feature branch
  2. Make your changes in a well-structured commit history
  3. Include tests (when applicable)
  4. Submit a pull request with a clear description of your changes

License

This project is licensed under the GNU Version 3 - see the LICENSE file for details.

Acknowledgments

TreeView is built on top of the excellent Charm ecosystem:

  • Bubble Tea for TUI framework
  • Lipgloss for styling and layout
  • VHS for epic scriptable demos
  • Charm community for inspiration and gif hosting!

Star History

Star History Chart


Documentation

Overview

Package treeview provides a flexible tree structure for building interactive terminal user interfaces. You can create trees from various data sources, navigate with keyboard controls, search and filter nodes, and customize rendering with your own styling.

The core Tree type manages a collection of Node instances and provides thread-safe operations for focusing, expanding, searching, and rendering. Trees support context cancellation and can be customized through functional options.

Basic usage:

tree := treeview.New(
	treeview.WithSearcher(mySearchFn),
)
renderedTree, err := tree.Render(ctx)

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrEmptyID is returned when a node is created with an empty ID string,
	// which would prevent proper tree construction and lookups.
	ErrEmptyID = errors.New("empty node ID")

	// ErrTraversalLimit is raised when TraversalCap
	// has been exceeded during a build or file-system scan.
	ErrTraversalLimit = errors.New("traversal limit exceeded")

	// ErrNodeNotFound is returned by lookup helpers when the requested node
	// does not exist in the tree.
	ErrNodeNotFound = errors.New("node not found in tree")

	// ErrCyclicReference is returned when building a tree encounters a cycle
	// in parent-child relationships.
	ErrCyclicReference = errors.New("cyclic reference detected in tree")

	// ErrTreeConstruction is returned when tree building fails at a high level.
	ErrTreeConstruction = errors.New("tree construction failed")

	// ErrFileSystem is returned when file system operations fail.
	ErrFileSystem = errors.New("file system operation failed")

	// ErrPathResolution is returned when a path cannot be resolved.
	ErrPathResolution = errors.New("path resolution failed")

	// ErrDirectoryScan is returned when directory scanning fails.
	ErrDirectoryScan = errors.New("directory scan failed")
)

Functions

func NormalizeIconWidth

func NormalizeIconWidth(icon string) string

NormalizeIconWidth pads or trims the icon so that the combined width of icon plus trailing space is at least targetWidth runes. This keeps labels neatly aligned under each other.

This is called during the rendering process, but it is more efficient to call it once for each icon before storing it in your provider to cache the result. No string concatenation is performed if the icon is already the correct width.

func PredAll

func PredAll[T any](predicates ...func(*Node[T]) bool) func(*Node[T]) bool

PredAll combines multiple predicates with logical AND. All predicates must return true for the combined predicate to return true.

func PredAny

func PredAny[T any](predicates ...func(*Node[T]) bool) func(*Node[T]) bool

PredAny combines multiple predicates with logical OR. At least one predicate must return true for the combined predicate to return true.

func PredContainsText

func PredContainsText[T any](text string) func(*Node[T]) bool

PredContainsText returns a predicate that checks if a node's name contains the given text. The comparison is case-insensitive.

func PredHasExtension

func PredHasExtension[T any](extensions ...string) func(*Node[T]) bool

PredHasExtension returns a predicate that checks if a node's name ends with any of the given extensions.

func PredHasName

func PredHasName[T any](name string) func(*Node[T]) bool

PredHasName returns a predicate that checks if a node's name equals the given name. The comparison is case-sensitive.

func PredHasNameIgnoreCase

func PredHasNameIgnoreCase[T any](name string) func(*Node[T]) bool

PredHasNameIgnoreCase returns a predicate that checks if a node's name equals the given name. The comparison is case-insensitive.

func PredIsCollapsed

func PredIsCollapsed[T any]() func(*Node[T]) bool

PredIsCollapsed returns a predicate that checks if a node is currently collapsed.

func PredIsDir

func PredIsDir[T any]() func(*Node[T]) bool

PredIsDir returns a predicate that checks if a node represents a directory. This works by checking if the node's data implements the IsDir() bool method.

func PredIsExpanded

func PredIsExpanded[T any]() func(*Node[T]) bool

PredIsExpanded returns a predicate that checks if a node is currently expanded.

func PredIsFile

func PredIsFile[T any]() func(*Node[T]) bool

PredIsFile returns a predicate that checks if a node represents a file. This is the inverse of PredIsDir.

func PredIsHidden

func PredIsHidden[T any]() func(*Node[T]) bool

PredIsHidden returns a predicate that checks if a node's name starts with a dot, indicating it's a hidden file or directory.

func PredMatchesRegex

func PredMatchesRegex[T any](pattern *regexp.Regexp) func(*Node[T]) bool

PredMatchesRegex returns a predicate that checks if a node's name matches the compiled regex pattern. Pass a compiled regexp.Regexp for efficient repeated matching.

func PredNot

func PredNot[T any](predicate func(*Node[T]) bool) func(*Node[T]) bool

PredNot negates a predicate.

Types

type DefaultNodeProvider

type DefaultNodeProvider[T any] struct {
	DisableIcons bool
	// contains filtered or unexported fields
}

DefaultNodeProvider is a batteries-included implementation of NodeProvider that delivers a pleasant out-of-the-box look & feel.

It is possible to tweak colours, icons, and type-specific styles via the exposed setter methods or replace the provider entirely with your own.

Icon theme ------------ A small internal map associates node types ("expanded", "collapsed", "file", …) with emoji glyphs. Call SetIcon/SetCollapsedIcon/SetExpandedIcon to override single entries or set DisableIcons to true to render a blank two-space placeholder instead.

Styles ------ Focused nodes get their own style variants, so they pop out during keyboard navigation. You can further specialise style choices per node type via SetTypeStyle.

func NewDefaultNodeProvider

func NewDefaultNodeProvider[T any](opts ...ProviderOption[T]) *DefaultNodeProvider[T]

NewDefaultNodeProvider returns a provider initialised with a reasonably neutral colour palette that should look okay on both dark and light terminals.

func NewFileNodeProvider

func NewFileNodeProvider[T any](opts ...ProviderOption[T]) *DefaultNodeProvider[T]

NewFileNodeProvider returns a pre-configured node provider with sensible defaults for rendering file system trees.

func (*DefaultNodeProvider[T]) Format

func (p *DefaultNodeProvider[T]) Format(node *Node[T]) string

Format returns the human-readable label for a node.

func (*DefaultNodeProvider[T]) Icon

func (p *DefaultNodeProvider[T]) Icon(node *Node[T]) string

Icon picks an icon for the node based on its type and expanded state.

func (*DefaultNodeProvider[T]) SetDefaultStyle

func (p *DefaultNodeProvider[T]) SetDefaultStyle(style lipgloss.Style)

SetDefaultStyle updates the style used when no type-specific override exists.

func (*DefaultNodeProvider[T]) SetFocusedStyle

func (p *DefaultNodeProvider[T]) SetFocusedStyle(style lipgloss.Style)

SetFocusedStyle changes the style applied to the focused node when no type-specific override exists.

func (*DefaultNodeProvider[T]) Style

func (p *DefaultNodeProvider[T]) Style(node *Node[T], isFocused bool) lipgloss.Style

Style returns the lipgloss style that should be applied to the main label of a node. Focus takes precedence over type-specific styles.

type ExpandFn

type ExpandFn[T any] func(node *Node[T]) bool

ExpandFn returns true if the node should be expanded during the build process.

type FileInfo

type FileInfo struct {
	os.FileInfo
	Path  string
	Extra map[string]any
}

FileInfo embeds os.FileInfo and adds the absolute Path so callers no longer need to juggle both pieces of information after a stat.

type FilterFn

type FilterFn[T any] func(item T) bool

FilterFn returns true if the item should be included in the tree.

type FlatDataProvider

type FlatDataProvider[T any] interface {
	ID(T) string
	Name(T) string
	ParentID(T) string
}

FlatDataProvider is the counterpart for BuildTreeFromFlatData. It exposes just the fundamental accessors needed to build nested data structures from flat data.

  • ID(T) string unique identifier for the item
  • Name(T) string display label for the node
  • ParentID(T) string identifier of the item's parent ("" for roots)

Optional construction behavior is handled separately via Options.

type FocusPolicyFn

type FocusPolicyFn[T any] func(ctx context.Context, visible []*Node[T], current *Node[T], offset int) (*Node[T], error)

FocusPolicyFn selects the next node to focus when the user moves up/down the list. The offset is usually ±1 but can be any integer.

type KeyMap

type KeyMap struct {
	// Navigation keys
	Quit     []string
	Up       []string
	Down     []string
	Expand   []string
	Collapse []string
	Toggle   []string
	Reset    []string

	// Multi-focus keys
	ExtendUp   []string
	ExtendDown []string

	// Search keys
	SearchStart  []string
	SearchAccept []string
	SearchCancel []string
	SearchDelete []string
}

KeyMap groups key bindings for the interactive TUI. Provide your own via WithTuiKeyMap if you need to accommodate non-US layouts or match existing shortcuts.

func DefaultKeyMap

func DefaultKeyMap() KeyMap

DefaultKeyMap returns a map of basic key bindings.

type MasterConfig added in v1.8.2

type MasterConfig[T any] struct {
	// contains filtered or unexported fields
}

MasterConfig is the structure that aggregates options from different domains (build, filesystem, tree). It is used by the unified constructors to collect and dispatch options to the appropriate internal functions.

func NewMasterConfig added in v1.8.2

func NewMasterConfig[T any](opts []Option[T], defaults ...Option[T]) *MasterConfig[T]

NewMasterConfig is a helper that creates a MasterConfig, applies defaults, and then user-provided options.

func (*MasterConfig[T]) HandleExpansion added in v1.8.2

func (cfg *MasterConfig[T]) HandleExpansion(node *Node[T])

HandleExpansion checks if a node should be expanded based on the configured expand function and expands it if true.

func (*MasterConfig[T]) HasDepthLimitBeenReached added in v1.8.2

func (cfg *MasterConfig[T]) HasDepthLimitBeenReached(currentDepth int) bool

HasDepthLimitBeenReached checks if the given current depth has reached or exceeded the configured maximum depth limit.

func (*MasterConfig[T]) HasTraversalCapBeenReached added in v1.8.2

func (cfg *MasterConfig[T]) HasTraversalCapBeenReached(nodeCount int) bool

HasTraversalCapBeenReached checks if the current node count has reached or exceeded the configured traversal cap.

func (*MasterConfig[T]) ReportProgress added in v1.8.2

func (cfg *MasterConfig[T]) ReportProgress(processed int, node *Node[T])

ReportProgress invokes the configured progress callback (if any).

func (*MasterConfig[T]) ShouldFilter added in v1.8.2

func (cfg *MasterConfig[T]) ShouldFilter(item T) bool

ShouldFilter evaluates whether the given item should be excluded based on the configured filter function.

type NestedDataProvider

type NestedDataProvider[T any] interface {
	ID(T) string
	Name(T) string
	Children(T) []T
}

NestedDataProvider is the counterpart for BuildTreeFromNestedData. It exposes just the fundamental accessors needed to traverse nested data structures.

  • ID(T) string unique identifier for the item
  • Name(T) string display label for the node
  • Children(T) []T direct descendants of the item

Optional construction behavior is handled separately via Options.

type Node

type Node[T any] struct {
	// contains filtered or unexported fields
}

Node represents a single element in a tree. It stores an arbitrary payload of type T along with helper metadata used by the renderer and traversal helpers. A Node is not safe for concurrent mutation; callers must synchronise if they modify Nodes from multiple goroutines.

ID and Name

ID   – stable, unique identifier used for look-ups and focus handling.
Name – optional human-readable label shown by default renderers.

The zero value of Node is NOT ready for use; always create nodes via NewNode, NewNodeSimple, NewNodeClone, or NewFileSystemNode so the invariants are set up correctly.

func NewFileSystemNode

func NewFileSystemNode(path string, info os.FileInfo) *Node[FileInfo]

NewFileSystemNode builds a FileSystemNode from a path and the corresponding os.FileInfo result. The function panics if info is nil because that would violate the contract of FileSystemNode.

func NewNode

func NewNode[T any](id, name string, data T) *Node[T]

NewNode constructs a Node with the supplied name and payload. Children are initially empty, the node is visible and collapsed.

func NewNodeClone

func NewNodeClone[T any](original *Node[T]) *Node[T]

NewNodeClone creates a copy of an existing node preserving its state (visible, expanded) but not its children or parent. This is useful when building filtered or depth-limited versions of trees where you need to preserve the original node's visual state.

func NewNodeSimple

func NewNodeSimple[T any](idAndName string, data T) *Node[T]

NewNodeSimple constructs a Node using the same string for both ID and name. This is a convenience method for cases where the identifier and display name are identical. The node is initially visible and collapsed with empty children.

func (*Node[T]) AddChild

func (n *Node[T]) AddChild(child *Node[T])

AddChild appends a single child and sets the reciprocal parent pointer.

func (*Node[T]) All

func (n *Node[T]) All(ctx context.Context) iter.Seq2[NodeInfo[T], error]

All (From Node) - Iterate from specific Node using depth-first traversal. Context errors are returned unwrapped.

func (*Node[T]) Children

func (n *Node[T]) Children() []*Node[T]

Children returns the direct descendants of the node.

func (*Node[T]) Collapse

func (n *Node[T]) Collapse()

Collapse hides all descendants of the node by flipping the expanded flag to false. Renderers and iterators will treat the node as a black box until you call Expand again.

func (*Node[T]) Data

func (n *Node[T]) Data() *T

Data exposes the payload you supplied when creating the node. As with any generic accessor, callers should assert the concrete type they expect.

func (*Node[T]) Expand

func (n *Node[T]) Expand()

Expand marks the node as expanded so its children become traversable and visible to renderers. No-op for leaf nodes.

func (*Node[T]) HasChildren

func (n *Node[T]) HasChildren() bool

HasChildren is a cheap helper for renderers and UIs that need to know if they should draw an expand/collapse icon next to the node.

func (*Node[T]) ID

func (n *Node[T]) ID() string

ID returns the stable identifier of the node.

The identifier is unique within a single tree and is the first port of call for operations like SetFocusedID, searches, and serialisation. Treat it as an immutable primary key.

func (*Node[T]) IsExpanded

func (n *Node[T]) IsExpanded() bool

IsExpanded reports whether Expand was called without a matching Collapse.

func (*Node[T]) IsVisible

func (n *Node[T]) IsVisible() bool

IsVisible returns the last value set via SetVisible.

func (*Node[T]) Name

func (n *Node[T]) Name() string

Name returns the human-readable label of the node. If you never set a distinct name the constructor falls back to using the ID so renderers can still show something sensible.

func (*Node[T]) Parent

func (n *Node[T]) Parent() *Node[T]

Parent returns the immediate ancestor or nil for root nodes.

func (*Node[T]) SetChildren

func (n *Node[T]) SetChildren(children []*Node[T])

SetChildren replaces the entire child slice and wires up the parent pointers.

func (*Node[T]) SetData

func (n *Node[T]) SetData(data T)

SetData replaces the payload stored inside the node.

func (*Node[T]) SetExpanded

func (n *Node[T]) SetExpanded(expanded bool)

SetExpanded sets the expanded state of the node.

func (*Node[T]) SetName

func (n *Node[T]) SetName(name string)

SetName updates the display label shown by renderers.

func (*Node[T]) SetVisible

func (n *Node[T]) SetVisible(visible bool)

SetVisible lets search and filter operations include or exclude the node from subsequent traversals without physically removing it from the tree.

func (*Node[T]) Toggle

func (n *Node[T]) Toggle()

Toggle is a convenience wrapper that switches between Expand and Collapse depending on the current state.

type NodeInfo

type NodeInfo[T any] struct {
	Node   *Node[T]
	Depth  int
	IsLast bool
}

NodeInfo is returned by iters and contains metadata about a node during iteration.

type NodeProvider

type NodeProvider[T any] interface {
	// Icon returns the leading glyph (e.g. folder / file symbol) for the node.
	Icon(node *Node[T]) string

	// Format converts the node's data into a human-readable label that follows the icon.
	Format(node *Node[T]) string

	// Style supplies the lipgloss style for the node based on its focus state.
	Style(node *Node[T], isFocused bool) lipgloss.Style
}

NodeProvider lets you plug custom rendering logic into treeview. The generic parameter T represents your domain object that is stored inside each Node.

A provider is responsible for supplying icon, text, and style attributes so the renderer can paint a line for a single node. You can return different styles depending on whether the node is currently focused in the TUI.

All methods must be safe for concurrent use because renderers may call them from multiple goroutines.

type Option added in v1.8.2

type Option[T any] func(*MasterConfig[T])

Option is the unified functional Option type used by all tree constructors. It allows callers to provide build-time and run-time configurations in a single, flat list.

func WithExpandAll

func WithExpandAll[T any]() Option[T]

WithExpandAll expands all nodes by default.

func WithExpandFunc

func WithExpandFunc[T any](fn ExpandFn[T]) Option[T]

WithExpandFunc installs a predicate that decides for each node whether it should start expanded.

func WithFilterFunc

func WithFilterFunc[T any](filter FilterFn[T]) Option[T]

WithFilterFunc installs a predicate that decides for each node whether it should be included in the tree.

func WithFocusPolicy

func WithFocusPolicy[T any](fn FocusPolicyFn[T]) Option[T]

WithFocusPolicy replaces the logic that decides which node should be focused after search or navigation.

func WithMaxDepth

func WithMaxDepth[T any](d int) Option[T]

WithMaxDepth limits how deep the walker descends into directories or other data structures. Use a negative depth for no limit (default).

func WithProgressCallback added in v1.6.0

func WithProgressCallback[T any](cb ProgressCallback[T]) Option[T]

WithProgressCallback registers a callback that is invoked each time a new node is created during any of the constructor build phases. It is not invoked by NewTree (which accepts pre-built nodes) except once per root node supplied so callers have a consistent hook.

func WithProvider

func WithProvider[T any](p NodeProvider[T]) Option[T]

WithProvider specifies the NodeProvider to use for rendering nodes. The provider controls how nodes are formatted, styled, and displayed.

func WithSearcher

func WithSearcher[T any](fn SearchFn[T]) Option[T]

WithSearcher overwrites the algorithm used when the search feature is invoked.

func WithTraversalCap

func WithTraversalCap[T any](cap int) Option[T]

WithTraversalCap sets an upper bound on the total number of entries visited during tree construction. A value ≤ 0 is interpreted as no limit.

func WithTruncate added in v1.8.0

func WithTruncate[T any](width int) Option[T]

WithTruncate sets the maximum width for rendered lines. Lines longer than this width will be truncated with an ellipsis. A width of 0 disables truncation (default).

type ProgressCallback added in v1.6.0

type ProgressCallback[T any] func(processed int, node *Node[T])

ProgressCallback is invoked during tree construction every time a node is created.

type ProviderOption

type ProviderOption[T any] func(*DefaultNodeProvider[T])

ProviderOption is a function that configures a DefaultNodeProvider.

func WithDefaultFileRules

func WithDefaultFileRules[T any]() ProviderOption[T]

WithDefaultFileRules is a provider Option that adds a default icon for file nodes. A node is considered a file if it is not a folder.

func WithDefaultFolderRules

func WithDefaultFolderRules[T any]() ProviderOption[T]

WithDefaultFolderRules is a provider Option that adds icon and style rules for folder nodes. A node is considered a folder if its data object implements the `IsDir() bool` method.

func WithDefaultIcon

func WithDefaultIcon[T any](icon string) ProviderOption[T]

WithDefaultIcon is a provider Option that sets the default icon for nodes that do not match any other icon rule.

func WithFileExtensionRules

func WithFileExtensionRules[T any]() ProviderOption[T]

WithFileExtensionRules is a provider Option that adds icon and style rules based on file extensions.

func WithFormatter

func WithFormatter[T any](formatter func(node *Node[T]) (string, bool)) ProviderOption[T]

WithFormatter adds a custom formatter for the node's label. The first formatter that returns true will be used.

func WithIconRule

func WithIconRule[T any](predicate func(*Node[T]) bool, icon string) ProviderOption[T]

WithIconRule is a provider Option that adds a custom icon rule. Rules are evaluated in the order they are added

func WithStyleRule

func WithStyleRule[T any](predicate func(*Node[T]) bool, style, focused lipgloss.Style) ProviderOption[T]

WithStyleRule is a provider Option that adds a custom style rule.

type SearchFn

type SearchFn[T any] func(ctx context.Context, node *Node[T], term string) bool

SearchFn returns true if the node matches the search term.

type Tree

type Tree[T any] struct {
	// contains filtered or unexported fields
}

Tree wraps a collection of nodes and offers rich operations such as filtering, searching, focusing, and rendering. All public methods are safe for concurrent use; a sync.RWMutex guards internal state.

func NewTree

func NewTree[T any](nodes []*Node[T], opts ...Option[T]) *Tree[T]

NewTree creates a new Tree from an existing slice of nodes.

Supported options:

  • WithFilterFunc: Filters nodes recursively, keeping parents with matching children
  • WithMaxDepth: Limits tree depth (0 = root only, 1 = root + children, etc.)
  • WithExpandFunc: Sets initial expansion state for nodes
  • WithProgressCallback: Reports progress for each provided root node
  • WithSearcher: Custom search algorithm
  • WithFocusPolicy: Custom focus navigation logic
  • WithProvider: Custom node rendering provider

Note: WithTraversalCap is not respected at this stage.

Note: WithFilterFunc, WithMaxDepth, and WithExpandFunc are provided for convenience, but they are not efficient. It is better to use the filter functions provided by the other constructors to filter, limit, and expand the tree during construction.

func NewTreeFromCfg added in v1.8.2

func NewTreeFromCfg[T any](nodes []*Node[T], cfg *MasterConfig[T]) *Tree[T]

NewTreeFromCfg creates a new Tree with the provided nodes and the configuration `cfg`.

func NewTreeFromFileSystem

func NewTreeFromFileSystem(
	ctx context.Context,
	path string,
	followSymlinks bool,
	opts ...Option[FileInfo],
) (*Tree[FileInfo], error)

NewTreeFromFileSystem creates a Tree that represents the filesystem hierarchy starting from the given root path. It is specialized for os.FileInfo data. Returns context errors unwrapped, or ErrFileSystem for filesystem errors.

Supported options: Build options:

  • WithFilterFunc: Filters items during tree building
  • WithMaxDepth: Limits tree depth during construction
  • WithExpandFunc: Sets initial expansion state for nodes
  • WithTraversalCap: Limits total nodes processed (returns partial tree + error if exceeded)
  • WithProgressCallback: Invoked after each filesystem entry is processed (breadth-first per directory)

Options used during a tree's runtime:

  • WithSearcher: Custom search algorithm
  • WithFocusPolicy: Custom focus navigation logic
  • WithProvider: Custom node rendering provider

func NewTreeFromFlatData

func NewTreeFromFlatData[T any](
	ctx context.Context,
	items []T,
	provider FlatDataProvider[T],
	opts ...Option[T],
) (*Tree[T], error)

NewTreeFromFlatData builds a Tree from a flat list of items, where each item references its parent by ID. This is useful for data from databases or APIs. Returns context errors unwrapped.

Example:

tree, err := treeview.NewTreeFromFlatData(
    ctx,
    employees,
    &EmployeeProvider{},
    treeview.WithExpandFunc(expandManagers),
    treeview.WithFilterFunc(filterActiveEmployees),
)

Supported options: Build options:

  • WithFilterFunc: Filters items during tree building
  • WithMaxDepth: Limits tree depth after hierarchy is built
  • WithExpandFunc: Sets initial expansion state for nodes
  • WithTraversalCap: Limits total nodes processed (returns partial tree + error if exceeded)
  • WithProgressCallback: Invoked after each node creation (flat pass order)

Options used during a tree's runtime:

  • WithSearcher: Custom search algorithm
  • WithFocusPolicy: Custom focus navigation logic
  • WithProvider: Custom node rendering provider

func NewTreeFromNestedData

func NewTreeFromNestedData[T any](
	ctx context.Context,
	items []T,
	provider NestedDataProvider[T],
	opts ...Option[T],
) (*Tree[T], error)

NewTreeFromNestedData builds a Tree from a data source where items are already structured in a parent-child hierarchy. The provider interface tells the builder how to access the ID, name, and children for each item. Returns context errors unwrapped.

Example:

tree, err := treeview.NewTreeFromNestedData(
    ctx,
    menuItems,
    &MenuProvider{},
    treeview.WithExpandFunc(expandTopLevel),
    treeview.WithMaxDepth(3),
)

Supported options: Build options:

  • WithFilterFunc: Filters items during tree building
  • WithMaxDepth: Limits tree depth during construction
  • WithExpandFunc: Sets initial expansion state for nodes
  • WithTraversalCap: Limits total nodes processed (returns partial tree + error if exceeded)
  • WithProgressCallback: Invoked after each node creation (depth-first)

Options used during a tree's runtime:

  • WithSearcher: Custom search algorithm
  • WithFocusPolicy: Custom focus navigation logic
  • WithProvider: Custom node rendering provider

func (*Tree[T]) AddFocusedID added in v1.1.0

func (t *Tree[T]) AddFocusedID(ctx context.Context, id string) error

AddFocusedID adds a node to the focused set. Returns ErrNodeNotFound if the ID doesn't exist.

func (*Tree[T]) All

func (t *Tree[T]) All(ctx context.Context) iter.Seq2[NodeInfo[T], error]

All returns an iterator that yields to every node using depth-first traversal. Context errors are returned unwrapped.

func (*Tree[T]) AllBottomUp added in v1.4.0

func (t *Tree[T]) AllBottomUp(ctx context.Context) iter.Seq2[NodeInfo[T], error]

AllBottomUp returns an iterator that yields nodes in bottom-up order (leaves first, then parents). Context errors are returned unwrapped.

func (*Tree[T]) AllFocused added in v1.1.0

func (t *Tree[T]) AllFocused(ctx context.Context) iter.Seq2[NodeInfo[T], error]

AllFocused returns an iterator over all focused nodes in the tree. Context errors are returned unwrapped.

func (*Tree[T]) AllVisible

func (t *Tree[T]) AllVisible(ctx context.Context) iter.Seq2[NodeInfo[T], error]

AllVisible returns an iterator over visible nodes using depth-first traversal. Context errors are returned unwrapped.

func (*Tree[T]) BreadthFirst

func (t *Tree[T]) BreadthFirst(ctx context.Context) iter.Seq2[NodeInfo[T], error]

BreadthFirst returns an iterator over nodes using breadth first traversal. Context errors are returned unwrapped.

func (*Tree[T]) ClearAllFocus added in v1.1.0

func (t *Tree[T]) ClearAllFocus()

ClearAllFocus clears all focused nodes.

func (*Tree[T]) CollapseAll

func (t *Tree[T]) CollapseAll(ctx context.Context) error

CollapseAll collapses every node. Returns context errors unwrapped.

func (*Tree[T]) ExpandAll

func (t *Tree[T]) ExpandAll(ctx context.Context) error

ExpandAll expands every node in the tree. Returns context errors unwrapped.

func (*Tree[T]) FindByID

func (t *Tree[T]) FindByID(ctx context.Context, id string) (*Node[T], error)

FindByID searches the tree for a node with the given ID. Returns ErrNodeNotFound if no node matches, or context errors unwrapped.

func (*Tree[T]) GetAllFocusedIDs added in v1.1.0

func (t *Tree[T]) GetAllFocusedIDs() []string

GetAllFocusedIDs returns the IDs of all currently focused nodes.

func (*Tree[T]) GetAllFocusedNodes added in v1.1.0

func (t *Tree[T]) GetAllFocusedNodes() []*Node[T]

GetAllFocusedNodes returns all currently focused nodes.

func (*Tree[T]) GetFocusedID

func (t *Tree[T]) GetFocusedID() string

GetFocusedID returns the ID of the currently focused node or "" if none.

func (*Tree[T]) GetFocusedNode

func (t *Tree[T]) GetFocusedNode() *Node[T]

GetFocusedNode returns the currently focused node or nil if none is focused.

func (*Tree[T]) HideAll

func (t *Tree[T]) HideAll(ctx context.Context) error

HideAll hides all nodes. Returns context errors unwrapped.

func (*Tree[T]) IsFocused added in v1.1.0

func (t *Tree[T]) IsFocused(id string) bool

IsFocused checks if the node with the given ID is currently focused.

func (*Tree[T]) Move

func (t *Tree[T]) Move(ctx context.Context, offset int) (bool, error)

Move changes the focus by offset within the list of currently visible nodes. Negative values move upward, positive downward. The bool result reports whether focus moved. Returns context errors unwrapped.

func (*Tree[T]) MoveExtend added in v1.1.0

func (t *Tree[T]) MoveExtend(ctx context.Context, offset int) (bool, error)

MoveExtend moves the primary focus by offset while preserving the existing multi-focus. If there's no existing multi-focus, it behaves like regular Move. The bool result reports whether focus moved.

func (*Tree[T]) Nodes

func (t *Tree[T]) Nodes() []*Node[T]

Nodes returns the current root slice. The caller must treat the returned slice as read-only unless they can guarantee exclusive access.

func (*Tree[T]) RemoveFocusedID added in v1.1.0

func (t *Tree[T]) RemoveFocusedID(ctx context.Context, id string) error

RemoveFocusedID removes a node from the focused set.

func (*Tree[T]) Render

func (t *Tree[T]) Render(ctx context.Context) (string, error)

Render produces a string representation of the tree using the configured renderer. Returns context errors unwrapped.

func (*Tree[T]) Search

func (t *Tree[T]) Search(ctx context.Context, term string) ([]*Node[T], error)

Search scans the tree for nodes matching term. Returns context errors unwrapped.

func (*Tree[T]) SearchAndExpand

func (t *Tree[T]) SearchAndExpand(ctx context.Context, term string) ([]*Node[T], error)

SearchAndExpand performs Search and then expands all ancestor nodes of each match so the results become visible. The first match is focused. Returns context errors unwrapped.

func (*Tree[T]) SetAllFocusedIDs added in v1.1.0

func (t *Tree[T]) SetAllFocusedIDs(ctx context.Context, ids []string) error

SetAllFocusedIDs sets the complete list of focused node IDs, replacing any existing focus.

func (*Tree[T]) SetExpanded

func (t *Tree[T]) SetExpanded(ctx context.Context, id string, expanded bool) (bool, error)

SetExpanded sets the expanded state of the given node. It returns false if the node wasn't found. Returns ErrNodeNotFound if the ID doesn't exist, or context errors unwrapped.

func (*Tree[T]) SetFocusedID

func (t *Tree[T]) SetFocusedID(ctx context.Context, id string) (bool, error)

SetFocusedID focuses the node with the given ID. An empty ID clears the focus. The boolean return value indicates whether the focus actually changed. Returns ErrNodeNotFound if the ID doesn't exist, or context errors unwrapped.

func (*Tree[T]) SetNodes added in v1.7.0

func (t *Tree[T]) SetNodes(nodes []*Node[T])

SetNodes replaces the root nodes of the tree. This is useful for removing root nodes or restructuring the tree. The operation is thread-safe.

func (*Tree[T]) ShowAll

func (t *Tree[T]) ShowAll(ctx context.Context) error

ShowAll shows all nodes. Returns context errors unwrapped.

func (*Tree[T]) ToggleFocused

func (t *Tree[T]) ToggleFocused(ctx context.Context)

ToggleFocused flips the expansion state of all focused nodes.

func (*Tree[T]) ToggleFocusedID added in v1.1.0

func (t *Tree[T]) ToggleFocusedID(ctx context.Context, id string) error

ToggleFocusedID toggles the focus state of the node with the given ID.

type TuiTreeModel

type TuiTreeModel[T any] struct {
	*Tree[T]
	// contains filtered or unexported fields
}

TuiTreeModel wraps a Tree and exposes it through a Bubble Tea model. It handles keyboard navigation, search, and viewport resizing.

Concurrency: All mutating operations are executed within the Tea event loop which is single-threaded, so internal state does not need extra locking.

func NewTuiTreeModel

func NewTuiTreeModel[T any](tree *Tree[T], opts ...TuiTreeModelOption[T]) *TuiTreeModel[T]

NewTuiTreeModel creates an interactive Bubble Tea TUI model using functional options. The zero-value configuration applies sensible defaults:

  • 100ms navigation timeout
  • 300ms search timeout
  • DefaultKeyMap for key bindings
  • DefaultNodeProvider if none specified

Example:

tree := treeview.NewTree(nodes, treeview.WithSearcher(customSearcher))
model := treeview.NewTuiTreeModel(
    tree,
    treeview.WithTuiWidth(80),
    treeview.WithTuiHeight(25),
)

func (*TuiTreeModel[T]) BeginSearch

func (m *TuiTreeModel[T]) BeginSearch()

BeginSearch switches the model into search mode and clears previous term.

func (*TuiTreeModel[T]) Collapse

func (m *TuiTreeModel[T]) Collapse()

Collapse collapses all currently focused nodes to hide their children.

func (*TuiTreeModel[T]) EndSearch

func (m *TuiTreeModel[T]) EndSearch()

EndSearch exits search mode and clears highlights.

func (*TuiTreeModel[T]) Expand

func (m *TuiTreeModel[T]) Expand()

Expand expands all currently focused nodes to show their children.

func (*TuiTreeModel[T]) ExtendFocusDown added in v1.1.0

func (m *TuiTreeModel[T]) ExtendFocusDown()

ExtendFocusDown extends the multi-focus selection downward by one node.

func (*TuiTreeModel[T]) ExtendFocusUp added in v1.1.0

func (m *TuiTreeModel[T]) ExtendFocusUp()

ExtendFocusUp extends the multi-focus selection upward by one node.

func (*TuiTreeModel[T]) Init

func (m *TuiTreeModel[T]) Init() tea.Cmd

Init initializes the TUI model. Required by the Bubble Tea model interface.

func (*TuiTreeModel[T]) NavBar

func (m *TuiTreeModel[T]) NavBar() string

NavBar returns the navigation bar string that shows available keyboard commands. This method is exposed so users can create custom navigation bars or extend the default one.

func (*TuiTreeModel[T]) NavigateDown

func (m *TuiTreeModel[T]) NavigateDown()

NavigateDown moves the focus one visible node down.

func (*TuiTreeModel[T]) NavigateUp

func (m *TuiTreeModel[T]) NavigateUp()

NavigateUp moves the focus one visible node up.

func (*TuiTreeModel[T]) Search

func (m *TuiTreeModel[T]) Search(term string) ([]*Node[T], error)

Search updates the term live as the user types and expands the tree so that matches are visible. It returns the result slice so external code can, for instance, display the hit count.

func (*TuiTreeModel[T]) Toggle

func (m *TuiTreeModel[T]) Toggle()

Toggle expands or collapses all currently focused nodes.

func (*TuiTreeModel[T]) Update

func (m *TuiTreeModel[T]) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update processes Bubble Tea messages and returns updated model and commands.

func (*TuiTreeModel[T]) View

func (m *TuiTreeModel[T]) View() string

View renders the tree plus an optional search bar and navigation legend.

type TuiTreeModelOption

type TuiTreeModelOption[T any] func(*TuiTreeModel[T])

TuiTreeModelOption represents a functional Option that configures a TuiTreeModel instance directly.

func WithTuiAllowResize

func WithTuiAllowResize[T any](allowResize bool) TuiTreeModelOption[T]

WithTuiAllowResize sets whether the viewport can be resized. Defaults to true.

func WithTuiDisableNavBar

func WithTuiDisableNavBar[T any](disable bool) TuiTreeModelOption[T]

WithTuiDisableNavBar disables the built-in navigation bar at the bottom of the view.

func WithTuiHeight

func WithTuiHeight[T any](h int) TuiTreeModelOption[T]

WithTuiHeight sets the viewport height.

func WithTuiKeyMap

func WithTuiKeyMap[T any](k KeyMap) TuiTreeModelOption[T]

WithTuiKeyMap allows callers to override the key bindings used by the model.

func WithTuiNavigationTimeout

func WithTuiNavigationTimeout[T any](d time.Duration) TuiTreeModelOption[T]

WithTuiNavigationTimeout sets the timeout for navigation operations.

func WithTuiSearchTimeout

func WithTuiSearchTimeout[T any](d time.Duration) TuiTreeModelOption[T]

WithTuiSearchTimeout sets the timeout for search operations.

func WithTuiWidth

func WithTuiWidth[T any](w int) TuiTreeModelOption[T]

WithTuiWidth sets the viewport width.

Directories

Path Synopsis
examples
shared
Package shared provides utilities and common functionality for TreeView v2 examples.
Package shared provides utilities and common functionality for TreeView v2 examples.
extensions
s3 module
internal

Jump to

Keyboard shortcuts

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