From 25f8b8c99b2d58e6995841b6f2693cda7403ea9f Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Fri, 15 May 2020 16:08:58 -0400 Subject: [PATCH] Simplify pager component and fix pager example --- examples/pager/main.go | 73 ++++++++++++++++++++++++++++++++++++++++-- pager/pager.go | 21 +++--------- 2 files changed, 75 insertions(+), 19 deletions(-) diff --git a/examples/pager/main.go b/examples/pager/main.go index 8268580..e752a84 100644 --- a/examples/pager/main.go +++ b/examples/pager/main.go @@ -10,20 +10,87 @@ import ( ) func main() { + + // Load some text to render content, err := ioutil.ReadFile("artichoke.md") if err != nil { fmt.Println("could not load file:", err) os.Exit(1) } + // Use the full size of the terminal in its "Alternate Screen Buffer" boba.AltScreen() defer boba.ExitAltScreen() + if err := boba.NewProgram( - pager.Init(string(content)), - pager.Update, - pager.View, + initialize(string(content)), + update, + view, ).Start(); err != nil { fmt.Println("could not run program:", err) os.Exit(1) } } + +type terminalSizeMsg struct { + width int + height int + err error +} + +func (t terminalSizeMsg) Size() (int, int) { return t.width, t.height } +func (t terminalSizeMsg) Error() error { return t.err } + +type model struct { + err error + content string + ready bool + pager pager.Model +} + +func initialize(content string) func() (boba.Model, boba.Cmd) { + return func() (boba.Model, boba.Cmd) { + return model{ + content: content, + }, getTerminalSize() + } +} + +func update(msg boba.Msg, mdl boba.Model) (boba.Model, boba.Cmd) { + m, _ := mdl.(model) + + switch msg := msg.(type) { + case boba.KeyMsg: + if msg.Type == boba.KeyCtrlC { + return m, boba.Quit + } + m.pager, _ = pager.Update(msg, m.pager) + case terminalSizeMsg: + if msg.Error() != nil { + m.err = msg.Error() + break + } + w, h := msg.Size() + m.pager = pager.NewModel(w, h) + m.pager.SetContent(m.content) + m.ready = true + } + + return m, nil +} + +func view(mdl boba.Model) string { + m, _ := mdl.(model) + if m.err != nil { + return "\nError:" + m.err.Error() + } else if m.ready { + return "\n" + pager.View(m.pager) + } + return "\nInitalizing..." +} + +func getTerminalSize() boba.Cmd { + return boba.GetTerminalSize(func(w, h int, err error) boba.TerminalSizeMsg { + return terminalSizeMsg{width: w, height: h, err: err} + }) +} diff --git a/pager/pager.go b/pager/pager.go index a6f01e9..5860f16 100644 --- a/pager/pager.go +++ b/pager/pager.go @@ -1,7 +1,6 @@ package pager import ( - "errors" "strings" "github.com/charmbracelet/boba" @@ -18,6 +17,7 @@ type Model struct { lines []string } +// Scrollpercent returns the amount scrolled as a float between 0 and 1 func (m Model) ScrollPercent() float64 { if m.Height >= len(m.lines) { return 1.0 @@ -34,6 +34,7 @@ func (m *Model) SetContent(s string) { m.lines = strings.Split(s, "\n") } +// NewModel creates a new pager model. Pass the dimensions of the pager. func NewModel(width, height int) Model { return Model{ Width: width, @@ -43,14 +44,7 @@ func NewModel(width, height int) Model { // UPDATE -func Update(msg boba.Msg, model boba.Model) (boba.Model, boba.Cmd) { - m, ok := model.(Model) - if !ok { - return Model{ - Err: errors.New("could not perform assertion on model in update in pager; are you sure you passed the correct model?"), - }, nil - } - +func Update(msg boba.Msg, m Model) (Model, boba.Cmd) { switch msg := msg.(type) { case boba.KeyMsg: @@ -103,18 +97,13 @@ func Update(msg boba.Msg, model boba.Model) (boba.Model, boba.Cmd) { } } - return model, nil + return m, nil } // VIEW // View renders the viewport into a string -func View(model boba.Model) string { - m, ok := model.(Model) - if !ok { - return "could not perform assertion on model in view in pager; are you sure you passed the correct model?" - } - +func View(m Model) string { if m.Err != nil { return m.Err.Error() }