package tui import ( "strings" "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/lerko/nib/internal/db" "github.com/lerko/nib/internal/parse" ) type inputResult struct { entity *db.Entity query bool body string tags []string } type inputModel struct { ti textinput.Model preview *parse.Result } func newInputModel() inputModel { ti := textinput.New() ti.Placeholder = "capture a thought…" ti.Prompt = inputPromptStyle.Render("› ") ti.CharLimit = 500 return inputModel{ti: ti} } func (i *inputModel) clearText() { i.ti.SetValue("") i.preview = nil } func (i inputModel) submit() *inputResult { val := i.ti.Value() if val == "" { return nil } parsed, err := parse.Parse(val) if err != nil { return nil } if parsed.Query { return &inputResult{ query: true, body: parsed.Body, tags: parsed.FilterTags, } } e := &db.Entity{ Body: parsed.Body, Title: parsed.Title, Glyph: db.Glyph(parsed.Glyph), Tags: parsed.Tags, } if parsed.TimeAnchor != nil { e.TimeAnchor = parsed.TimeAnchor } if parsed.CardSuffix != nil { ct := db.CardType(*parsed.CardSuffix) e.CardType = &ct } if parsed.Pin { e.Pinned = true } if parsed.Description != nil { e.Description = parsed.Description } return &inputResult{entity: e} } func (i inputModel) updateKey(msg tea.KeyMsg) inputModel { i.ti, _ = i.ti.Update(msg) val := i.ti.Value() if val != "" { parsed, err := parse.Parse(val) if err == nil { i.preview = parsed } else { i.preview = nil } } else { i.preview = nil } return i } func (i inputModel) viewBar(width int, focused bool) string { tiView := i.ti.View() if focused { return tiView } val := i.ti.Value() if val != "" { return hintDescStyle.Render("› " + val) } return hintDescStyle.Render("› capture a thought…") } func (i inputModel) previewText() string { if i.preview == nil { return "" } p := i.preview if p.Query { q := "?" if p.Body != "" { q += p.Body } for _, t := range p.FilterTags { q += " #" + t } return "search: " + q } glyph := glyphForParsed(p.Glyph) body := p.Body if p.Title != nil { body = *p.Title } var parts []string parts = append(parts, glyph, body) for _, t := range p.Tags { parts = append(parts, "#"+t) } if p.Pin { parts = append(parts, "•") } if p.CardSuffix != nil { parts = append(parts, *p.CardSuffix) } return strings.Join(parts, " ") } func glyphForParsed(glyph string) string { switch glyph { case "todo": return "○" case "event": return "◇" case "reminder": return "△" default: return "—" } }