mirror of
https://github.com/charmbracelet/glow.git
synced 2026-08-21 07:34:18 +02:00
Stash documents from the stash view
This commit is contained in:
parent
3572ef5470
commit
04b6089bd9
3 changed files with 106 additions and 45 deletions
37
ui/pager.go
37
ui/pager.go
|
|
@ -65,7 +65,6 @@ func newStyle(fg, bg string) func(string) string {
|
|||
|
||||
type contentRenderedMsg string
|
||||
type noteSavedMsg *charm.Markdown
|
||||
type statusMessageTimeoutMsg struct{}
|
||||
type stashSuccessMsg markdown
|
||||
type stashErrMsg struct {
|
||||
err error
|
||||
|
|
@ -228,19 +227,7 @@ func pagerUpdate(msg tea.Msg, m pagerModel) (pagerModel, tea.Cmd) {
|
|||
// Stash a local document
|
||||
if m.state != pagerStateStashing && m.currentDocument.markdownType == localMarkdown {
|
||||
m.state = pagerStateStashing
|
||||
|
||||
// Create new markdown based on loaded markdown
|
||||
md := m.currentDocument
|
||||
md.markdownType = stashedMarkdown
|
||||
t := time.Now()
|
||||
md.CreatedAt = t
|
||||
|
||||
// Set the note as the filename without the extension
|
||||
p := md.localPath
|
||||
md.Note = strings.Replace(path.Base(p), path.Ext(p), "", 1)
|
||||
md.localPath = ""
|
||||
|
||||
return m, stashDocument(m.cc, md)
|
||||
return m, stashDocument(m.cc, m.currentDocument)
|
||||
}
|
||||
case "?":
|
||||
m.toggleHelp()
|
||||
|
|
@ -278,8 +265,11 @@ func pagerUpdate(msg tea.Msg, m pagerModel) (pagerModel, tea.Cmd) {
|
|||
m.state = pagerStateStatusMessage
|
||||
m.statusMessageHeader = "Stashed!"
|
||||
m.statusMessageBody = ""
|
||||
if m.statusMessageTimer != nil {
|
||||
m.statusMessageTimer.Stop()
|
||||
}
|
||||
m.statusMessageTimer = time.NewTimer(time.Second * 3)
|
||||
cmds = append(cmds, waitForStatusMessageTimeout(m.statusMessageTimer))
|
||||
cmds = append(cmds, waitForStatusMessageTimeout(pagerContext, m.statusMessageTimer))
|
||||
|
||||
case stashErrMsg:
|
||||
// TODO
|
||||
|
|
@ -474,6 +464,16 @@ func stashDocument(cc *charm.Client, md markdown) tea.Cmd {
|
|||
return stashErrMsg{err}
|
||||
}
|
||||
}
|
||||
|
||||
// Turn local markdown into a stashed markdown
|
||||
md.markdownType = stashedMarkdown
|
||||
md.CreatedAt = time.Now()
|
||||
|
||||
// Set the note as the filename without the extension
|
||||
p := md.localPath
|
||||
md.Note = strings.Replace(path.Base(p), path.Ext(p), "", 1)
|
||||
md.localPath = ""
|
||||
|
||||
return func() tea.Msg {
|
||||
err := cc.StashMarkdown(md.Note, md.Body)
|
||||
if err != nil {
|
||||
|
|
@ -486,13 +486,6 @@ func stashDocument(cc *charm.Client, md markdown) tea.Cmd {
|
|||
}
|
||||
}
|
||||
|
||||
func waitForStatusMessageTimeout(t *time.Timer) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
<-t.C
|
||||
return statusMessageTimeoutMsg{}
|
||||
}
|
||||
}
|
||||
|
||||
// This is where the magic happens
|
||||
func glamourRender(m pagerModel, markdown string) (string, error) {
|
||||
|
||||
|
|
|
|||
70
ui/stash.go
70
ui/stash.go
|
|
@ -142,6 +142,10 @@ type stashModel struct {
|
|||
// than we can display at a time so we can paginate locally without having
|
||||
// to fetch every time.
|
||||
page int
|
||||
|
||||
showStatusMessage bool
|
||||
statusMessage string
|
||||
statusMessageTimer *time.Timer
|
||||
}
|
||||
|
||||
func (m *stashModel) setSize(width, height int) {
|
||||
|
|
@ -197,6 +201,13 @@ func (m stashModel) countMarkdowns(t markdownType) (found int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (m *stashModel) hideStatusMessage() {
|
||||
m.showStatusMessage = false
|
||||
if m.statusMessageTimer != nil {
|
||||
m.statusMessageTimer.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
// INIT
|
||||
|
||||
func newStashModel() stashModel {
|
||||
|
|
@ -289,13 +300,33 @@ func stashUpdate(msg tea.Msg, m stashModel) (stashModel, tea.Cmd) {
|
|||
m.markdowns[i].Note = msg.Note
|
||||
}
|
||||
}
|
||||
|
||||
// Something was stashed. Add it to the stash listing.
|
||||
case stashSuccessMsg:
|
||||
md := markdown(msg)
|
||||
m.addMarkdowns(&md)
|
||||
|
||||
m.showStatusMessage = true
|
||||
m.statusMessage = "Stashed!"
|
||||
if m.statusMessageTimer != nil {
|
||||
m.statusMessageTimer.Stop()
|
||||
}
|
||||
m.statusMessageTimer = time.NewTimer(time.Second * 3)
|
||||
cmds = append(cmds, waitForStatusMessageTimeout(stashContext, m.statusMessageTimer))
|
||||
|
||||
case statusMessageTimeoutMsg:
|
||||
if applicationContext(msg) == stashContext {
|
||||
m.hideStatusMessage()
|
||||
}
|
||||
}
|
||||
|
||||
switch m.state {
|
||||
case stashStateReady:
|
||||
|
||||
switch msg := msg.(type) {
|
||||
|
||||
// Handle keys
|
||||
if msg, ok := msg.(tea.KeyMsg); ok {
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
|
||||
case "k", "up":
|
||||
|
|
@ -323,6 +354,8 @@ func stashUpdate(msg tea.Msg, m stashModel) (stashModel, tea.Cmd) {
|
|||
|
||||
// Open document
|
||||
case "enter":
|
||||
m.hideStatusMessage()
|
||||
|
||||
if len(m.markdowns) == 0 {
|
||||
break
|
||||
}
|
||||
|
|
@ -342,6 +375,8 @@ func stashUpdate(msg tea.Msg, m stashModel) (stashModel, tea.Cmd) {
|
|||
|
||||
// Set note
|
||||
case "m":
|
||||
m.hideStatusMessage()
|
||||
|
||||
md := m.selectedMarkdown()
|
||||
isUserMarkdown := md.markdownType == stashedMarkdown
|
||||
isSettingNote := m.state == stashStateSettingNote
|
||||
|
|
@ -354,8 +389,17 @@ func stashUpdate(msg tea.Msg, m stashModel) (stashModel, tea.Cmd) {
|
|||
return m, textinput.Blink(m.noteInput)
|
||||
}
|
||||
|
||||
// Stash
|
||||
case "s":
|
||||
md := m.selectedMarkdown()
|
||||
if md != nil && md.markdownType == localMarkdown {
|
||||
cmds = append(cmds, stashDocument(m.cc, *md))
|
||||
}
|
||||
|
||||
// Prompt for deletion
|
||||
case "x":
|
||||
m.hideStatusMessage()
|
||||
|
||||
isUserMarkdown := m.selectedMarkdown().markdownType == stashedMarkdown
|
||||
isValidState := m.state != stashStateSettingNote
|
||||
|
||||
|
|
@ -500,11 +544,15 @@ func stashView(m stashModel) string {
|
|||
}
|
||||
|
||||
var header string
|
||||
switch m.state {
|
||||
case stashStatePromptDelete:
|
||||
header = redFg("Delete this item? ") + faintRedFg("(y/N)")
|
||||
case stashStateSettingNote:
|
||||
header = yellowFg("Set the memo for this item?")
|
||||
if m.showStatusMessage {
|
||||
header = greenFg(m.statusMessage)
|
||||
} else {
|
||||
switch m.state {
|
||||
case stashStatePromptDelete:
|
||||
header = redFg("Delete this item? ") + faintRedFg("(y/N)")
|
||||
case stashStateSettingNote:
|
||||
header = yellowFg("Set the memo for this item?")
|
||||
}
|
||||
}
|
||||
|
||||
// Only draw the normal header if we're not using the header area for
|
||||
|
|
@ -619,11 +667,13 @@ func stashHelpView(m stashModel) string {
|
|||
var (
|
||||
h []string
|
||||
isStashed bool
|
||||
isLocal bool
|
||||
)
|
||||
|
||||
if len(m.markdowns) > 0 {
|
||||
md := m.selectedMarkdown()
|
||||
isStashed = md != nil && md.markdownType == stashedMarkdown
|
||||
isLocal = md != nil && md.markdownType == localMarkdown
|
||||
}
|
||||
|
||||
if m.state == stashStateSettingNote {
|
||||
|
|
@ -640,13 +690,15 @@ func stashHelpView(m stashModel) string {
|
|||
if m.paginator.TotalPages > 1 {
|
||||
h = append(h, "h/l, ←/→: page")
|
||||
}
|
||||
if isStashed && len(m.markdowns) > 0 {
|
||||
if isStashed {
|
||||
h = append(h, []string{"x: delete", "m: set memo"}...)
|
||||
} else if isLocal {
|
||||
h = append(h, "s: stash")
|
||||
}
|
||||
if m.err != nil {
|
||||
h = append(h, []string{"!: errors"}...)
|
||||
h = append(h, "!: errors")
|
||||
}
|
||||
h = append(h, []string{"q: quit"}...)
|
||||
h = append(h, "q: quit")
|
||||
}
|
||||
return stashHelpViewBuilder(m.terminalWidth, h...)
|
||||
}
|
||||
|
|
|
|||
44
ui/ui.go
44
ui/ui.go
|
|
@ -6,6 +6,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/bubbles/spinner"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
|
|
@ -52,13 +53,9 @@ func NewProgram(style string, cfg Config) *tea.Program {
|
|||
type errMsg error
|
||||
type newCharmClientMsg *charm.Client
|
||||
type sshAuthErrMsg struct{}
|
||||
type keygenFailedMsg struct {
|
||||
err error
|
||||
}
|
||||
type keygenFailedMsg struct{ err error }
|
||||
|
||||
func (k keygenFailedMsg) Error() string {
|
||||
return k.err.Error()
|
||||
}
|
||||
func (k keygenFailedMsg) Error() string { return k.err.Error() }
|
||||
|
||||
type keygenSuccessMsg struct{}
|
||||
type initLocalFileSearchMsg struct {
|
||||
|
|
@ -70,19 +67,26 @@ type localFileSearchFinished struct{}
|
|||
type gotStashMsg []*charm.Markdown
|
||||
type stashLoadErrMsg struct{ err error }
|
||||
|
||||
func (s stashLoadErrMsg) Error() string {
|
||||
return s.err.Error()
|
||||
}
|
||||
func (s stashLoadErrMsg) Error() string { return s.err.Error() }
|
||||
|
||||
type gotNewsMsg []*charm.Markdown
|
||||
type newsLoadErrMsg struct{ err error }
|
||||
|
||||
func (s newsLoadErrMsg) Error() string {
|
||||
return s.err.Error()
|
||||
}
|
||||
func (s newsLoadErrMsg) Error() string { return s.err.Error() }
|
||||
|
||||
type statusMessageTimeoutMsg applicationContext
|
||||
|
||||
// MODEL
|
||||
|
||||
// Which part of the application something appies to. Occasionally used as an
|
||||
// arguments to command and messages.
|
||||
type applicationContext int
|
||||
|
||||
const (
|
||||
stashContext applicationContext = iota
|
||||
pagerContext
|
||||
)
|
||||
|
||||
type state int
|
||||
|
||||
const (
|
||||
|
|
@ -335,8 +339,13 @@ func update(msg tea.Msg, mdl tea.Model) (tea.Model, tea.Cmd) {
|
|||
// Something was stashed. Update the stash listing. We're caching this
|
||||
// here, rather than in the stash update function, because stashing
|
||||
// may have occurred in the pager.
|
||||
md := markdown(msg)
|
||||
m.stash.addMarkdowns(&md)
|
||||
if m.state == stateShowDocument {
|
||||
newStashModel, cmd := stashUpdate(msg, m.stash)
|
||||
m.stash = newStashModel
|
||||
if cmd != nil {
|
||||
cmds = append(cmds, cmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process children
|
||||
|
|
@ -497,6 +506,13 @@ func generateSSHKeys() tea.Msg {
|
|||
return keygenSuccessMsg{}
|
||||
}
|
||||
|
||||
func waitForStatusMessageTimeout(appCtx applicationContext, t *time.Timer) tea.Cmd {
|
||||
return func() tea.Msg {
|
||||
<-t.C
|
||||
return statusMessageTimeoutMsg(appCtx)
|
||||
}
|
||||
}
|
||||
|
||||
// ETC
|
||||
|
||||
// Convert local file path to Markdown. Note that we could be doing things
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue