-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
package main
import (
"fmt"
"strings"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
type model struct {
variables []variable
index int
editing bool
input textinput.Model
addingNew bool
}
type variable struct {
key string
value string
}
func initialModel() model {
// Initialize with default variables
defaultVars := []variable{
{"manage_filesystem", "true"},
{"update_packages", "true"},
{"install_requirements", "true"},
{"install_motd", "true"},
{"username", "sthings"},
{"lvm_home_sizing", "'15%'"},
{"lvm_root_sizing", "'35%'"},
{"lvm_var_sizing", "'50%'"},
{"send_to_msteams", "true"},
{"reboot_all", "false"},
}
input := textinput.New()
input.Prompt = "> "
input.Width = 50
return model{
variables: defaultVars,
input: input,
}
}
func (m model) Init() tea.Cmd {
return nil
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "esc":
return m, tea.Quit
case "enter":
if m.editing {
// Save edited value
if m.addingNew {
// Split input into key+-value
parts := strings.Split(m.input.Value(), "+-")
if len(parts) == 2 {
m.variables = append(m.variables, variable{
key: parts[0],
value: parts[1],
})
}
m.addingNew = false
} else {
// Update existing value
m.variables[m.index].value = m.input.Value()
}
m.editing = false
m.input.Blur()
} else {
// Start editing
m.editing = true
if m.addingNew {
m.input.SetValue("")
} else {
m.input.SetValue(m.variables[m.index].value)
}
m.input.Focus()
}
case "n":
if !m.editing {
m.addingNew = true
m.editing = true
m.input.SetValue("")
m.input.Focus()
}
case "up":
if m.index > 0 && !m.editing {
m.index--
}
case "down":
if m.index < len(m.variables)-1 && !m.editing {
m.index++
}
case "backspace":
if !m.editing && len(m.variables) > 0 {
// Delete current line
m.variables = append(m.variables[:m.index], m.variables[m.index+1:]...)
if m.index >= len(m.variables) {
m.index = len(m.variables) - 1
}
}
}
}
if m.editing {
m.input, cmd = m.input.Update(msg)
}
return m, cmd
}
func (m model) View() string {
var sb strings.Builder
// Title
title := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#FAFAFA")).
Background(lipgloss.Color("#7D56F4")).
Padding(0, 1).
Render("Edit Ansible Variables (key+-value)")
sb.WriteString(title + "\n\n")
// Variables list
for i, v := range m.variables {
line := fmt.Sprintf("%s+-%s", v.key, v.value)
if i == m.index {
if m.editing && !m.addingNew {
// Show input field for editing
line = fmt.Sprintf("%s+-%s",
lipgloss.NewStyle().Foreground(lipgloss.Color("#04B575")).Render(v.key),
m.input.View(),
)
} else {
// Highlight selected line
line = lipgloss.NewStyle().
Background(lipgloss.Color("#04B575")).
Render(line)
}
}
sb.WriteString(line + "\n")
}
// Adding new line
if m.addingNew && m.editing {
sb.WriteString("\nNew variable:\n")
sb.WriteString(m.input.View() + "+-")
}
// Help text
help := lipgloss.NewStyle().Faint(true).Render(`
↑/↓: Navigate • Enter: Edit/Save • n: Add New
Backspace: Delete • Esc: Exit
`)
sb.WriteString("\n" + help)
return sb.String()
}
func main() {
p := tea.NewProgram(initialModel())
if _, err := p.Run(); err != nil {
fmt.Printf("Error: %v", err)
return
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels