package main import ( "encoding/csv" "os" "os/exec" "strings" tea "charm.land/bubbletea/v2" ) type model struct { choices [][]string cursor int selected map[int]struct{} } func listModel(arg string) model { out, err := exec.Command("hugo", "list", arg).Output() if err != nil { println("Error fetching Hugo drafts: Is this a Hugo site? Is Hugo installed?") os.Exit(1) } csvReader := csv.NewReader(strings.NewReader(string(out))) records, err := csvReader.ReadAll() if err != nil { println("Error parsing draft list.") os.Exit(1) } if len(records) <= 1 { println("No drafts found.") os.Exit(1) } // remove the table head row records = records[1:] return model{ choices: records, selected: make(map[int]struct{}), } } func (m model) Init() tea.Cmd { return nil } func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyPressMsg: switch msg.String() { case "ctrl+c", "q": return m, tea.Quit case "up", "k": if m.cursor > 0 { m.cursor-- } case "down", "j": if m.cursor < len(m.choices)-1 { m.cursor++ } case "enter": choice := m.choices[m.cursor] path := choice[0] return m, openEditor(path) case "space": _, ok := m.selected[m.cursor] if ok { delete(m.selected, m.cursor) } else { m.selected[m.cursor] = struct{}{} } } case editorFinishedMsg: return m, tea.Quit } return m, nil }