From 5019331dff465a973d30785d1b6dfcd0d4649002 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Wed, 3 Jun 2020 14:17:41 -0400 Subject: [PATCH] Mini help view for pager --- go.mod | 1 + go.sum | 3 --- ui/pager.go | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--- ui/ui.go | 1 + 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 087369d..a542632 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac github.com/muesli/reflow v0.1.0 github.com/muesli/termenv v0.6.0 + github.com/mattn/go-runewidth v0.0.9 github.com/spf13/cobra v0.0.7 golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 // indirect diff --git a/go.sum b/go.sum index 837b176..454b0bb 100644 --- a/go.sum +++ b/go.sum @@ -15,12 +15,10 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/calmh/randomart v1.1.0 h1:evl+iwc10LXtHdMZhzLxmsCQVmWnkXs44SbC6Uk0Il8= github.com/calmh/randomart v1.1.0/go.mod h1:DQUbPVyP+7PAs21w/AnfMKG5NioxS3TbZ2F9MSK/jFM= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/charmbracelet/bubbles v0.0.0-20200526000837-87c7cd778f80 h1:cfaoL1+tHPABTLEAg831PIFG96teW69Wamz9M025r5M= github.com/charmbracelet/bubbles v0.0.0-20200526000837-87c7cd778f80/go.mod h1:/AeLRFlL2Uf4X7U5LjnswTII6u4maPzMm1+vZfeUJKc= github.com/charmbracelet/bubbles v0.0.0-20200602224800-12b2758d50f2 h1:JDEhuhIiBwpnd/3f0o/4pjYobUTnTU+sxvDMCDC/D78= github.com/charmbracelet/bubbles v0.0.0-20200602224800-12b2758d50f2/go.mod h1:/AeLRFlL2Uf4X7U5LjnswTII6u4maPzMm1+vZfeUJKc= github.com/charmbracelet/bubbletea v0.6.4-0.20200525234836-3b8b011b5a26/go.mod h1:BTzHOUvUlKecQz7ZB8NgPRWi2Z8NRCV04qwyFOfO1Kk= -github.com/charmbracelet/bubbletea v0.7.0 h1:nf0FEQCCc1e0qRGgpnz08QFsy25eDitzVwxV+Z/p4UI= github.com/charmbracelet/bubbletea v0.7.0/go.mod h1:BTzHOUvUlKecQz7ZB8NgPRWi2Z8NRCV04qwyFOfO1Kk= github.com/charmbracelet/bubbletea v0.7.1-0.20200528144715-b10f6d679158 h1:aOjBpErc3ZM0KYma+JSRcWk5UZx/Tat9lnrzrflb+GM= github.com/charmbracelet/bubbletea v0.7.1-0.20200528144715-b10f6d679158/go.mod h1:DzNhKkQQJI30eb+kBcaOs1+z86zTSqcMgSHoFY+uCsg= @@ -180,7 +178,6 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602100848-8d3cce7afc34 h1:u6CI7A++8r4SItZHYe2cWeAEndN4p1p+3Oum/Ft2EzM= golang.org/x/sys v0.0.0-20200602100848-8d3cce7afc34/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/ui/pager.go b/ui/pager.go index 3b4b1e0..2a31b7e 100644 --- a/ui/pager.go +++ b/ui/pager.go @@ -13,6 +13,7 @@ import ( "github.com/charmbracelet/charm" "github.com/charmbracelet/charm/ui/common" "github.com/charmbracelet/glamour" + runewidth "github.com/mattn/go-runewidth" te "github.com/muesli/termenv" ) @@ -27,6 +28,8 @@ const ( ) var ( + pagerHelpHeight = strings.Count(pagerHelpView(0), "\n") + noteHeading = te.String(noteHeadingText). Foreground(common.Cream.Color()). Background(common.Green.Color()). @@ -45,6 +48,16 @@ var ( Foreground(statusBarNoteFg.Color()). Background(statusBarBg.Color()). Styled + + statusBarHelpStyle = te.Style{}. + Foreground(statusBarNoteFg.Color()). + Background(common.NewColorPair("#323232", "#DCDCDC").Color()). + Styled + + helpViewStyle = te.Style{}. + Foreground(statusBarNoteFg.Color()). + Background(common.NewColorPair("#1B1B1B", "#f2f2f2").Color()). + Styled ) // MSG @@ -69,6 +82,7 @@ type pagerModel struct { width int height int textInput textinput.Model + showHelp bool // Current document being rendered, sans-glamour rendering. We cache // this here so we can re-render it on resize. @@ -100,6 +114,10 @@ func (m *pagerModel) setSize(w, h int) { m.viewport.Width = w m.viewport.Height = h - statusBarHeight m.textInput.Width = w - len(noteHeadingText) - len(notePromptText) - 1 + + if m.showHelp { + m.viewport.Height -= pagerHelpHeight + 1 + } } func (m *pagerModel) setContent(s string) { @@ -164,6 +182,9 @@ func pagerUpdate(msg tea.Msg, m pagerModel) (pagerModel, tea.Cmd) { m.textInput.CursorEnd() } return m, textinput.Blink(m.textInput) + case "?": + m.showHelp = !m.showHelp + m.setSize(m.width, m.height) } } @@ -213,6 +234,10 @@ func pagerView(m pagerModel) string { pagerStatusBarView(&b, m) } + if m.showHelp { + fmt.Fprintf(&b, pagerHelpView(m.width)) + } + return b.String() } @@ -225,23 +250,31 @@ func pagerStatusBarView(b *strings.Builder, m pagerModel) { scrollPercent := math.Max(0.0, math.Min(1.0, m.viewport.ScrollPercent())) percentText := fmt.Sprintf(" %3.f%% ", scrollPercent*100) + // "Help" note + helpNoteText := " ? Help " + helpNote := statusBarHelpStyle(helpNoteText) + // Note noteText := m.currentDocument.Note if len(noteText) == 0 { noteText = "(No title)" } - noteText = truncate(" "+noteText+" ", max(0, m.width-len(logoText)-len(percentText))) + noteText = truncate(" "+noteText+" ", max( + 0, + m.width-len(logoText)-len(percentText)-len(helpNoteText), + )) // Empty space emptyCell := te.String(" ").Background(statusBarBg.Color()).String() - padding := max(0, m.width-len(logoText)-len(noteText)-len(percentText)) + padding := max(0, m.width-len(logoText)-len(noteText)-len(percentText)-len(helpNoteText)) emptySpace := strings.Repeat(emptyCell, padding) - fmt.Fprintf(b, "%s%s%s%s", + fmt.Fprintf(b, "%s%s%s%s%s", logo, statusBarNoteStyle(noteText), emptySpace, statusBarScrollPosStyle(percentText), + helpNote, ) } @@ -250,6 +283,32 @@ func pagerSetNoteView(b *strings.Builder, m pagerModel) { fmt.Fprint(b, textinput.View(m.textInput)) } +func pagerHelpView(width int) (s string) { + s += "\n" + s += "k/↑ up m set memo\n" + s += "j/↓ down esc/q back to stash\n" + s += "b/pgup page up\n" + s += "d/pgdn page down\n" + s += "u ½ page up\n" + s += "d ½ page down" + + s = indent(s, 2) + + // Fill up empty cells with spaces for background coloring + if width > 0 { + lines := strings.Split(s, "\n") + for i := 0; i < len(lines); i++ { + l := runewidth.StringWidth(lines[i]) + n := width - l + lines[i] += strings.Repeat(" ", n) + } + + s = strings.Join(lines, "\n") + } + + return helpViewStyle(s) +} + // CMD func renderWithGlamour(m pagerModel, md string) tea.Cmd { diff --git a/ui/ui.go b/ui/ui.go index 007fb87..a322445 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -83,6 +83,7 @@ func (m *model) unloadDocument() { m.state = stateShowStash m.stash.state = stashStateReady m.pager.unload() + m.pager.showHelp = false } // INIT