devtui

package module
v0.0.115 Latest Latest
Warning

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

Go to latest
Published: Jul 22, 2025 License: MIT Imports: 17 Imported by: 0

README

DevTUI

Project Badges

Interactive Terminal User Interface library for Go applications development (principal tui in GoDEV App)

devtui

Quick Start

DevTUI uses a handler-based architecture where fields implement the FieldHandler interface for automatic async operations and message tracking.

package main

import (
    "fmt"
    "strings"
    "sync"
    "time"
    "github.com/cdvelop/devtui"
)

// Handler implementing both interfaces
type HostHandler struct {
    currentHost string
    lastOpID    string
}

// WritingHandler methods
func (h *HostHandler) Name() string { return "HostHandler" }
func (h *HostHandler) SetLastOperationID(id string) { h.lastOpID = id }
func (h *HostHandler) GetLastOperationID() string { return h.lastOpID }

// FieldHandler methods  
func (h *HostHandler) Label() string { return "Host" }
func (h *HostHandler) Value() string { return h.currentHost }
func (h *HostHandler) Editable() bool { return true }
func (h *HostHandler) Timeout() time.Duration { return 5 * time.Second }
func (h *HostHandler) Change(newValue any, progress ...func(string)) (string, error) {
    host := strings.TrimSpace(newValue.(string))
    if host == "" {
        return "", fmt.Errorf("host cannot be empty")
    }
    
    // Use progress callback for real-time updates
    if len(progress) > 0 {
        progressCallback := progress[0]
        progressCallback("Validating host configuration...")
        time.Sleep(500 * time.Millisecond)
        progressCallback("Checking network connectivity...")
        time.Sleep(500 * time.Millisecond)
        progressCallback("Host validation complete")
    } else {
        time.Sleep(1 * time.Second) // Fallback for sync execution
    }
    
    h.currentHost = host
    return fmt.Sprintf("Host configured: %s", host), nil
}

func main() {
    tui := devtui.NewTUI(&devtui.TuiConfig{
        AppName: "MyApp",
        ExitChan: make(chan bool),
    })
    
    tui.NewTabSection("Server", "Configuration").
        NewField(&HostHandler{currentHost: "localhost"})

    var wg sync.WaitGroup
    wg.Add(1)
    go tui.Start(&wg)
    wg.Wait()
}

Interfaces

type FieldHandler interface {
    WritingHandler                                      // Embedded for message tracking
    Label() string                                      // Field display name
    Value() string                                      // Current field value
    Editable() bool                                     // true=input, false=action
    Change(newValue any, progress ...func(string)) (string, error) // Handle changes with progress
    Timeout() time.Duration                             // Operation timeout
}

type WritingHandler interface {
    Name() string                          // Handler identifier (must be unique)
    SetLastOperationID(id string)         // Set operation ID for message updates
    GetLastOperationID() string           // Get operation ID for message reuse
}

Features

  • Dynamic Progress Messages: Real-time progress updates with custom messages
  • Message Update In-Place: Operations update existing messages instead of creating new ones
  • Handler-based Architecture: Clean separation of concerns with interface-based design
  • Automatic Async Operations: Operations run asynchronously with progress feedback
  • Operation ID Tracking: Messages are tracked and updated using operation IDs
  • Configurable Timeouts: Each handler can specify its own timeout duration
  • Multiple Handler Instances: Same handler type can have multiple instances with unique names

Progress Callback Usage

The Change method receives an optional progress callback that can be used to provide real-time feedback:

func (h *BuildHandler) Change(newValue any, progress ...func(string)) (string, error) {
    if len(progress) > 0 {
        progressCallback := progress[0]
        
        // Simple message updates
        progressCallback("Initiating build process...")
        time.Sleep(500 * time.Millisecond)
        
        progressCallback("Compiling source code...")
        time.Sleep(1 * time.Second)
        
        progressCallback("Build complete")
    }
    
    return "Build completed successfully", nil
}

Each progress call updates the same message line in the TUI, providing smooth real-time feedback without cluttering the interface.

Important Notes

Handler Name Uniqueness

When using multiple instances of the same handler type, ensure each has a unique name:

type BuildHandler struct {
    buildType string
    lastOpID  string
}

func (h *BuildHandler) Name() string { 
    return fmt.Sprintf("Build_%s", h.buildType) // Unique per instance
}

// Usage
prodBuild := &BuildHandler{buildType: "Production"}
devBuild := &BuildHandler{buildType: "Development"}

This ensures each handler maintains its own message history and updates correctly.

Navigation

  • Tab/Shift+Tab: Switch between tabs
  • Left/Right: Navigate fields within tab
  • Enter: Edit/Execute
  • Esc: Cancel edit
  • Ctrl+C: Exit

Documentation

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ColorStyle

type ColorStyle struct {
	Foreground string // eg: #F4F4F4
	Background string // eg: #000000
	Highlight  string // eg: #FF6600
	Lowlight   string // eg: #666666
}

type DevTUI

type DevTUI struct {
	*TuiConfig
	// contains filtered or unexported fields
}

DevTUI mantiene el estado de la aplicación

func NewTUI

func NewTUI(c *TuiConfig) *DevTUI

NewTUI creates a new DevTUI instance and initializes it.

Usage Example:

config := &TuiConfig{
    AppName: "MyApp",
    TabIndexStart: 0,
    ExitChan: make(chan bool),
    Color: nil, // or your *ColorStyle
    LogToFile: func(err any) { fmt.Println(err) },
}
tui := NewTUI(config)

// Configure your sections and fields:
tui.NewTabSection("My Section", "Description").
	NewField("Field1", "value", true, nil)

// Start the TUI:
var wg sync.WaitGroup
wg.Add(1)
go tui.Run(&wg)
wg.Wait()

func (*DevTUI) AddTabSections added in v0.0.9

func (t *DevTUI) AddTabSections(sections ...*tabSection) *DevTUI

AddTabSections adds one or more tabSections to the DevTUI If a tab with title "DEFAULT" exists, it will be replaced by the first tab section Deprecated: Use NewTabSection and append to tabSections directly

func (*DevTUI) ContentView

func (h *DevTUI) ContentView() string

ContentView renderiza los mensajes para una sección de contenido

func (*DevTUI) GetTotalTabSections added in v0.0.9

func (t *DevTUI) GetTotalTabSections() int

GetTotalTabSections returns the total number of tab sections

func (*DevTUI) HandleKeyboard added in v0.0.10

func (h *DevTUI) HandleKeyboard(msg tea.KeyMsg) (bool, tea.Cmd)

HandleKeyboard processes keyboard input and updates the model state returns whether the update function should continue processing or return early

func (*DevTUI) Init

func (h *DevTUI) Init() tea.Cmd

Init initializes the terminal UI application.

func (*DevTUI) NewTabSection added in v0.0.43

func (t *DevTUI) NewTabSection(title, footer string) *tabSection

NewTabSection creates and initializes a new tabSection with the given title and footer NewTabSection creates a new tab section and automatically adds it to the TUI

Example:

tab := tui.NewTabSection("BUILD", "Press enter to compile")

func (*DevTUI) Print

func (h *DevTUI) Print(messages ...any)

Print sends a normal Label or error to the tui in current tab

func (*DevTUI) ReturnFocus

func (t *DevTUI) ReturnFocus() error

func (*DevTUI) Start added in v0.0.93

func (h *DevTUI) Start(args ...any)

Start initializes and runs the terminal UI application.

It accepts optional variadic arguments of any type. If a *sync.WaitGroup is provided among these arguments, Start will call its Done() method before returning.

The method runs the UI using the internal tea engine, and handles any errors that may occur during execution. If an error occurs, it will be displayed on the console and the application will wait for user input before exiting.

Parameters:

  • args ...any: Optional arguments. Can include a *sync.WaitGroup for synchronization.

func (*DevTUI) Update

func (h *DevTUI) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update maneja las actualizaciones del estado

func (*DevTUI) View

func (h *DevTUI) View() string

type FieldHandler added in v0.0.7

type FieldHandler interface {
	Label() string                                                 // Field label (e.g., "Server Port")
	Value() string                                                 // Current field value (e.g., "8080")
	Editable() bool                                                // Whether field is editable or action button
	Change(newValue any, progress ...func(string)) (string, error) // Handler with optional progress callback
	Timeout() time.Duration                                        // Return 0 for no timeout, or specific duration

	// NEW: WritingHandler methods (REQUIRED for all handlers)
	WritingHandler
}

FieldHandler interface defines the contract for field handlers This replaces the individual parameters approach with a unified interface

type HandlerWriter added in v0.0.103

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

NEW: HandlerWriter wraps tabSection with handler identification

func (*HandlerWriter) Write added in v0.0.103

func (hw *HandlerWriter) Write(p []byte) (n int, err error)

type ShortcutsHandler added in v0.0.96

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

ShortcutsHandler - Shows keyboard navigation instructions

func NewShortcutsHandler added in v0.0.96

func NewShortcutsHandler() *ShortcutsHandler

func (*ShortcutsHandler) Change added in v0.0.96

func (h *ShortcutsHandler) Change(newValue any, progress ...func(string)) (string, error)

func (*ShortcutsHandler) Editable added in v0.0.96

func (h *ShortcutsHandler) Editable() bool

func (*ShortcutsHandler) GetLastOperationID added in v0.0.103

func (h *ShortcutsHandler) GetLastOperationID() string

func (*ShortcutsHandler) Label added in v0.0.96

func (h *ShortcutsHandler) Label() string

func (*ShortcutsHandler) Name added in v0.0.103

func (h *ShortcutsHandler) Name() string

WritingHandler methods

func (*ShortcutsHandler) SetLastOperationID added in v0.0.103

func (h *ShortcutsHandler) SetLastOperationID(lastOpID string)

func (*ShortcutsHandler) Timeout added in v0.0.96

func (h *ShortcutsHandler) Timeout() time.Duration

func (*ShortcutsHandler) Value added in v0.0.96

func (h *ShortcutsHandler) Value() string

type TuiConfig

type TuiConfig struct {
	AppName       string    // app name eg: "MyApp"
	TabIndexStart int       // is the index of the tab section to start default 0
	ExitChan      chan bool //  global chan to close app eg: make(chan bool)
	/* *ColorStyle style for the TUI
	 if nil it will use default style:
	type ColorStyle struct {
	 Foreground string // eg: #F4F4F4
	 Background string // eg: #000000
	 Highlight  string // eg: #FF6600
	 Lowlight   string // eg: #666666
	}*/
	Color *ColorStyle

	LogToFile func(messages ...any) // function to write log error
	TestMode  bool                  // only used in tests to enable synchronous behavior
}

type WritingHandler added in v0.0.103

type WritingHandler interface {
	Name() string                       // Handler identifier (e.g., "TinyWasm", "MainServer")
	SetLastOperationID(lastOpID string) // DevTUI calls this after processing each message
	GetLastOperationID() string         // Handler returns ID for message updates, "" for new messages
}

WritingHandler interface provides message source identification and operation ID management ALL handlers must implement this interface for message source control

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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