From bcad5fc9583cde2c462a85ddff9601183b97e4ff Mon Sep 17 00:00:00 2001 From: eltrac Date: Wed, 4 Mar 2026 10:44:03 +0800 Subject: refactor: divide main.go into modules --- main.go | 117 ----------------------------------------------------------- model.go | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ utilities.go | 22 +++++++++++ 3 files changed, 133 insertions(+), 117 deletions(-) create mode 100644 model.go create mode 100644 utilities.go diff --git a/main.go b/main.go index d987bf9..5196dd4 100644 --- a/main.go +++ b/main.go @@ -1,129 +1,12 @@ package main import ( - "encoding/csv" "fmt" "os" - "os/exec" - "strings" - "time" tea "charm.land/bubbletea/v2" ) -type model struct { - choices [][]string - cursor int - selected map[int]struct{} -} - -type editorFinishedMsg struct { - err error -} - -func initialModel() model { - out, err := exec.Command("hugo", "list", "drafts").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) - } - - return model{ - choices: records, - selected: make(map[int]struct{}), - } -} - -func (m model) Init() tea.Cmd { - return nil -} - -func openEditor(path string) tea.Cmd { - editor := os.Getenv("EDITOR") - if editor == "" { - editor = "vim" - } - return tea.ExecProcess(exec.Command(editor, path), func(err error) tea.Msg { - return editorFinishedMsg{err: err} - }) -} - -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 -} - -func (m model) View() tea.View { - s := "Unpublished drafts of this Hugo site:\n\n" - - for i, choice := range m.choices { - if i == 0 { - continue - } - - cursor := " " // no cursor - if m.cursor == i { - cursor = ">" - } - - checked := " " // not checked - if _, ok := m.selected[i]; ok { - checked = "x" - } - - title := choice[2] - t, err := time.Parse(time.RFC3339, choice[3]) - if err != nil { - - } - datetime := t.Format("2006-01-02 15:04") - - s += fmt.Sprintf("%s [%s] %s \t %s\n", cursor, checked, datetime, title) - } - - s += "\n[q] quit | [Enter] edit | [SPACE] select | [↑/k] up | [↓/j] down\n" - - return tea.NewView(s) -} - func main() { p := tea.NewProgram(initialModel()) if _, err := p.Run(); err != nil { diff --git a/model.go b/model.go new file mode 100644 index 0000000..059cfd2 --- /dev/null +++ b/model.go @@ -0,0 +1,111 @@ +package main + +import ( + "encoding/csv" + "fmt" + "os" + "os/exec" + "strings" + "time" + + tea "charm.land/bubbletea/v2" +) + +type model struct { + choices [][]string + cursor int + selected map[int]struct{} +} + +func initialModel() model { + out, err := exec.Command("hugo", "list", "drafts").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) + } + + 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 +} + +func (m model) View() tea.View { + s := "Unpublished drafts of this Hugo site:\n\n" + + for i, choice := range m.choices { + if i == 0 { + continue + } + + cursor := " " // no cursor + if m.cursor == i { + cursor = ">" + } + + checked := " " // not checked + if _, ok := m.selected[i]; ok { + checked = "x" + } + + title := choice[2] + t, err := time.Parse(time.RFC3339, choice[3]) + if err != nil { + + } + datetime := t.Format("2006-01-02 15:04") + + s += fmt.Sprintf("%s [%s] %s \t %s\n", cursor, checked, datetime, title) + } + + s += "\n[q] quit | [Enter] edit | [SPACE] select | [↑/k] up | [↓/j] down\n" + + return tea.NewView(s) +} diff --git a/utilities.go b/utilities.go new file mode 100644 index 0000000..5a9b69f --- /dev/null +++ b/utilities.go @@ -0,0 +1,22 @@ +package main + +import ( + "os" + "os/exec" + + tea "charm.land/bubbletea/v2" +) + +type editorFinishedMsg struct { + err error +} + +func openEditor(path string) tea.Cmd { + editor := os.Getenv("EDITOR") + if editor == "" { + editor = "vim" + } + return tea.ExecProcess(exec.Command(editor, path), func(err error) tea.Msg { + return editorFinishedMsg{err: err} + }) +} -- cgit v1.2.3