yedit

package module
v0.52.0 Latest Latest
Warning

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

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

README

yedit logo

A TUI YAML editor library for Go applications, built on bubbletea. Drop it into any CLI tool to give users a structured, schema-aware editor for their configuration files.

What it does

  • Can be embedded in any Go CLI tool, or used as a standalone editor for YAML files.
  • Schema is defined by a Go struct and a metadata tree, so you can use the same schema for validation, doc generation, and editor behavior.
  • Opens a YAML file in a split-pane TUI: block list on the left, YAML editor on the right.
  • Supports editing of nested structs, lists, and maps with a tree view and a [N] navigator.
  • Handles self-referential (recursive) struct types, with a configurable expansion depth.
  • Lets you hide fields from the UI or pass them through untouched, without changing your Go struct.
  • Displays per-field hints, types, defaults, and examples in a side panel.
  • Validates the YAML on save with a declarative rule set.
  • Flags unknown keys that aren't part of your schema.
  • Supports presets, two-level undo/redo, nested drill-in editing, and theming.
  • Generates Markdown reference docs from your schema.

Install

go get github.com/lucasassuncao/yedit

Minimal example

Each struct declares only its own direct fields; nested structs that also implement MetadataProvider are composed automatically.

package main

import (
	"log"

	"github.com/lucasassuncao/yedit/editor"
	"github.com/lucasassuncao/yedit/metadata"
)

type ServerConfig struct {
	Host string `yaml:"host"`
	Port int    `yaml:"port"`
}

func (ServerConfig) Metadata() map[string]*metadata.Node {
	return map[string]*metadata.Node{
		"host": {FieldMeta: editor.FieldMeta{Description: "Address to bind.", Default: "localhost"}},
		"port": {FieldMeta: editor.FieldMeta{Description: "Port to listen on.", Default: "8080"}},
	}
}

type Config struct {
	Server ServerConfig `yaml:"server"`
}

func (Config) Metadata() map[string]*metadata.Node {
	return map[string]*metadata.Node{
		"server": {FieldMeta: editor.FieldMeta{Description: "HTTP server configuration."}},
		// no Children needed - ServerConfig.Metadata() is composed automatically
	}
}

func main() {
	src, err := metadata.New(Config{})
	if err != nil {
		log.Fatal(err)
	}

	if _, err := editor.Run(editor.Config{
		Path:        "config.yaml",
		Schema:      &Config{},
		Metadata:    src,
		EnableHints: true,
	}); err != nil {
		log.Fatal(err)
	}
}

Escape hatch: metadata.NewFromTree for structs you don't own

Use this when the root struct comes from a third-party package and can't implement Metadata(). You assemble the full tree manually and pass it alongside the struct pointer.

package main

import (
	"log"

	"github.com/lucasassuncao/yedit/editor"
	"github.com/lucasassuncao/yedit/metadata"
)

type Config struct {
	Server struct {
		Host string `yaml:"host"`
		Port int    `yaml:"port"`
	} `yaml:"server"`
}

func main() {
	src, err := metadata.NewFromTree(&Config{}, map[string]*metadata.Node{
		"server": {
			Children: map[string]*metadata.Node{
				"host": {FieldMeta: editor.FieldMeta{Description: "Address to bind.", Default: "localhost"}},
				"port": {FieldMeta: editor.FieldMeta{Description: "Port to listen on.", Default: "8080"}},
			},
		},
	})
	if err != nil {
		log.Fatal(err)
	}

	if _, err := editor.Run(editor.Config{
		Path:        "config.yaml",
		Schema:      &Config{},
		Metadata:    src,
		EnableHints: true,
	}); err != nil {
		log.Fatal(err)
	}
}

Documentation

Document Contents
Getting Started Full happy path: struct → metadata → editor.Run, validators, presets, and doc generation
Config Reference Every editor.Config field in one table
Schema Kinds Reference How Go types map to editor behavior (KindObject, KindList, KindDictionary, KindVariant, …)
Validators Reference All built-in validation rules with examples
Presets PresetSource configuration for the block/document preset picker
Metadata and Hints MetadataSource configuration for the Hint/Example panel
Interaction Model Key bindings and tree action matrix
Undo & Redo The two-level undo model (block editor vs document) and what is and isn't tracked
Themes Built-in themes and how to customize colors
Doc Generation Generating Markdown reference docs from your schema
Session Tracing Config.Trace.Dump and the OnAction/OnModelAction/OnMsg hooks for recording a session
Known Limitations Dependency behaviors that can surprise you, including a silent data-rewrite caveat

Internals (for contributing to yedit itself, not for embedding it):

Document Contents
Architecture Package layout and design rationale
Dispatch Flow Component hierarchy, pane state machine, and message dispatch mechanics
Development Guide Makefile commands and the full VHS demo-recording workflow

Demo

demo

Example

examples/test is a small, self-contained editor demonstrating nested structs, the [N] list navigator, presets, validation, and hints. Run it from the repo root:

cd examples/test
go run . [--theme grape]     # open the editor
go run . generate-docs       # write docs/ markdown files

See examples/ for focused, recorded demos of each feature.

Documentation

Overview

Package yedit provides reusable building blocks for TUI editors over structured YAML files.

The library is composed of independent sub-packages:

  • schema: reflection over the client's Go structs (yaml tags only)
  • metadata: tree-based MetadataSource with strict schema validation
  • document: YAML state with block-level mutations, history, and parsing
  • editor: two-panel bubbletea TUI that ties the pieces together
  • presets: Source interface + struct-backed helpers (ForField, Combine) for per-field YAML snippets
  • viewer: read-only TUI to browse a preset Source
  • docgenerator: markdown docs generated from a schema + MetadataSource, with a TUI browser
  • theme: palette and layout primitives (header, panels, two-column layout)
  • alert: modal alert/confirm component shared by the TUIs
  • yamlnode: query and navigation helpers over yaml.v3 node trees
  • render: small shared rendering helpers (glamour YAML fence)

yedit is intentionally headless of any specific YAML schema. Clients pass a pointer to their own annotated struct and (optionally) a preset Source; the editor introspects the struct via the schema package and renders an add/edit/remove UI keyed by the canonical top-level order.

See editor.Run and editor.Config for the main entry point.

Directories

Path Synopsis
Package alert provides a modal alert/confirm component for bubbletea TUIs.
Package alert provides a modal alert/confirm component for bubbletea TUIs.
Package docgenerator generates markdown documentation files from a struct-based schema (via schema.Discover) and a MetadataSource.
Package docgenerator generates markdown documentation files from a struct-based schema (via schema.Discover) and a MetadataSource.
Package document provides primitives for editing YAML files structured as a flat mapping of top-level keys ("blocks").
Package document provides primitives for editing YAML files structured as a flat mapping of top-level keys ("blocks").
Package editor provides the bubbletea TUI for editing a YAML file driven by a struct-based schema and a preset source.
Package editor provides the bubbletea TUI for editing a YAML file driven by a struct-based schema and a preset source.
Package metadata provides a tree-based implementation of spec.MetadataSource.
Package metadata provides a tree-based implementation of spec.MetadataSource.
Package presets provides helpers for building a YAML preset source from Go structs.
Package presets provides helpers for building a YAML preset source from Go structs.
Package render holds rendering helpers shared by the editor and viewer TUIs.
Package render holds rendering helpers shared by the editor and viewer TUIs.
Package schema discovers the editable shape of a Go struct via reflection over yaml tags.
Package schema discovers the editable shape of a Go struct via reflection over yaml tags.
Package spec holds the vocabulary shared by everything that describes a configuration field: the editor, the validation rules, the metadata tree, and the documentation generator.
Package spec holds the vocabulary shared by everything that describes a configuration field: the editor, the validation rules, the metadata tree, and the documentation generator.
Package theme provides the palette, base lipgloss styles, and shared layout primitives used across yedit-built TUIs.
Package theme provides the palette, base lipgloss styles, and shared layout primitives used across yedit-built TUIs.
Package themebrowser provides a small, inline (not full-screen) terminal table listing yedit's built-in theme names next to their category.
Package themebrowser provides a small, inline (not full-screen) terminal table listing yedit's built-in theme names next to their category.
Package viewer is a read-only TUI that browses the presets exposed by a presets.Source.
Package viewer is a read-only TUI that browses the presets exposed by a presets.Source.
Package yamlnode provides read-mostly query and navigation helpers over gopkg.in/yaml.v3 node trees, shared by the editor's editing flow and its validators.
Package yamlnode provides read-mostly query and navigation helpers over gopkg.in/yaml.v3 node trees, shared by the editor's editing flow and its validators.

Jump to

Keyboard shortcuts

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