mirror of
https://github.com/charmbracelet/glow
synced 2024-11-10 06:04:18 +00:00
Replace bit-based document type implementation with a set-based one
This commit is contained in:
parent
7fabcea06d
commit
4c63c62bfa
8 changed files with 189 additions and 69 deletions
5
main.go
5
main.go
|
@ -289,14 +289,15 @@ func runTUI(stashedOnly bool) error {
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg.DocumentTypes = ui.NewDocTypeSet()
|
||||||
cfg.ShowAllFiles = showAllFiles
|
cfg.ShowAllFiles = showAllFiles
|
||||||
cfg.GlamourMaxWidth = width
|
cfg.GlamourMaxWidth = width
|
||||||
cfg.GlamourStyle = style
|
cfg.GlamourStyle = style
|
||||||
|
|
||||||
if stashedOnly {
|
if stashedOnly {
|
||||||
cfg.DocumentTypes = ui.StashedDocument | ui.NewsDocument
|
cfg.DocumentTypes.Add(ui.StashedDoc, ui.NewsDoc)
|
||||||
} else if localOnly {
|
} else if localOnly {
|
||||||
cfg.DocumentTypes = ui.LocalDocument
|
cfg.DocumentTypes.Add(ui.LocalDoc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run Bubble Tea program
|
// Run Bubble Tea program
|
||||||
|
|
78
ui/doctypes.go
Normal file
78
ui/doctypes.go
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package ui
|
||||||
|
|
||||||
|
// DocType represents a type of markdown document.
|
||||||
|
type DocType int
|
||||||
|
|
||||||
|
// Available document types.
|
||||||
|
const (
|
||||||
|
LocalDoc DocType = iota
|
||||||
|
StashedDoc
|
||||||
|
ConvertedDoc
|
||||||
|
NewsDoc
|
||||||
|
)
|
||||||
|
|
||||||
|
// DocTypeSet is a set (in the mathematic sense) of document types.
|
||||||
|
type DocTypeSet map[DocType]struct{}
|
||||||
|
|
||||||
|
// NewDocTypeSet returns a set of document types.
|
||||||
|
func NewDocTypeSet(t ...DocType) DocTypeSet {
|
||||||
|
d := DocTypeSet(make(map[DocType]struct{}))
|
||||||
|
if len(t) > 0 {
|
||||||
|
d.Add(t...)
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adds a document type of the set.
|
||||||
|
func (d *DocTypeSet) Add(t ...DocType) int {
|
||||||
|
for _, v := range t {
|
||||||
|
(*d)[v] = struct{}{}
|
||||||
|
}
|
||||||
|
return len(*d)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Had returns whether or not the set contains the given DocTypes.
|
||||||
|
func (d DocTypeSet) Contains(m ...DocType) bool {
|
||||||
|
matches := 0
|
||||||
|
for _, t := range m {
|
||||||
|
if _, found := d[t]; found {
|
||||||
|
matches++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matches == len(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Difference return a DocumentType set that does not contain the given types.
|
||||||
|
func (d DocTypeSet) Difference(t ...DocType) DocTypeSet {
|
||||||
|
c := copyDocumentTypes(d)
|
||||||
|
for k := range c {
|
||||||
|
for _, docType := range t {
|
||||||
|
if k == docType {
|
||||||
|
delete(c, k)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equals returns whether or not the two sets are equal.
|
||||||
|
func (d DocTypeSet) Equals(other DocTypeSet) bool {
|
||||||
|
return d.Contains(other.asSlice()...) && len(d) == len(other)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d DocTypeSet) asSlice() (agg []DocType) {
|
||||||
|
for k := range d {
|
||||||
|
agg = append(agg, k)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a copy of the given DocumentTypes map.
|
||||||
|
func copyDocumentTypes(d DocTypeSet) DocTypeSet {
|
||||||
|
c := make(map[DocType]struct{})
|
||||||
|
for k, v := range d {
|
||||||
|
c[k] = v
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
48
ui/doctypes_test.go
Normal file
48
ui/doctypes_test.go
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDocTypeContains(t *testing.T) {
|
||||||
|
d := NewDocTypeSet(LocalDoc)
|
||||||
|
|
||||||
|
if !d.Contains(LocalDoc) {
|
||||||
|
t.Error("Contains reported it doesn't contain a value which it absolutely does contain")
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Contains(NewsDoc) {
|
||||||
|
t.Error("Contains reported the set contains a value it certainly does not")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDocTypeDifference(t *testing.T) {
|
||||||
|
original := NewDocTypeSet(LocalDoc, StashedDoc, ConvertedDoc, NewsDoc)
|
||||||
|
difference := original.Difference(LocalDoc, NewsDoc)
|
||||||
|
expected := NewDocTypeSet(StashedDoc, ConvertedDoc)
|
||||||
|
|
||||||
|
// Make sure the difference operation worked
|
||||||
|
if !reflect.DeepEqual(difference, expected) {
|
||||||
|
t.Errorf("difference returned %+v; expected %+v", difference, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure original set was not mutated
|
||||||
|
if reflect.DeepEqual(original, difference) {
|
||||||
|
t.Errorf("original set was mutated when it should not have been")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDocTypeEquality(t *testing.T) {
|
||||||
|
a := NewDocTypeSet(LocalDoc, StashedDoc)
|
||||||
|
b := NewDocTypeSet(LocalDoc, StashedDoc)
|
||||||
|
c := NewDocTypeSet(LocalDoc)
|
||||||
|
|
||||||
|
if !a.Equals(b) {
|
||||||
|
t.Errorf("Equality test failed for %+v and %+v; expected true, got false", a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.Equals(c) {
|
||||||
|
t.Errorf("Equality test failed for %+v and %+v; expected false, got true", a, c)
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,18 +13,9 @@ import (
|
||||||
"golang.org/x/text/unicode/norm"
|
"golang.org/x/text/unicode/norm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DocumentType byte
|
|
||||||
|
|
||||||
const (
|
|
||||||
LocalDocument DocumentType = 1 << iota
|
|
||||||
StashedDocument
|
|
||||||
ConvertedDocument
|
|
||||||
NewsDocument
|
|
||||||
)
|
|
||||||
|
|
||||||
// markdown wraps charm.Markdown.
|
// markdown wraps charm.Markdown.
|
||||||
type markdown struct {
|
type markdown struct {
|
||||||
markdownType DocumentType
|
markdownType DocType
|
||||||
|
|
||||||
// Full path of a local markdown file. Only relevant to local documents and
|
// Full path of a local markdown file. Only relevant to local documents and
|
||||||
// those that have been stashed in this session.
|
// those that have been stashed in this session.
|
||||||
|
@ -53,7 +44,7 @@ func (m *markdown) buildFilterValue() {
|
||||||
// sortAsLocal returns whether or not this markdown should be sorted as though
|
// sortAsLocal returns whether or not this markdown should be sorted as though
|
||||||
// it's a local markdown document.
|
// it's a local markdown document.
|
||||||
func (m markdown) sortAsLocal() bool {
|
func (m markdown) sortAsLocal() bool {
|
||||||
return m.markdownType == LocalDocument || m.markdownType == ConvertedDocument
|
return m.markdownType == LocalDoc || m.markdownType == ConvertedDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort documents with local files first, then by date.
|
// Sort documents with local files first, then by date.
|
||||||
|
@ -108,7 +99,7 @@ func isMn(r rune) bool {
|
||||||
|
|
||||||
// wrapMarkdowns wraps a *charm.Markdown with a *markdown in order to add some
|
// wrapMarkdowns wraps a *charm.Markdown with a *markdown in order to add some
|
||||||
// extra metadata.
|
// extra metadata.
|
||||||
func wrapMarkdowns(t DocumentType, md []*charm.Markdown) (m []*markdown) {
|
func wrapMarkdowns(t DocType, md []*charm.Markdown) (m []*markdown) {
|
||||||
for _, v := range md {
|
for _, v := range md {
|
||||||
m = append(m, &markdown{
|
m = append(m, &markdown{
|
||||||
markdownType: t,
|
markdownType: t,
|
||||||
|
|
12
ui/pager.go
12
ui/pager.go
|
@ -215,8 +215,8 @@ func (m pagerModel) update(msg tea.Msg) (pagerModel, tea.Cmd) {
|
||||||
cmds = append(cmds, viewport.Sync(m.viewport))
|
cmds = append(cmds, viewport.Sync(m.viewport))
|
||||||
}
|
}
|
||||||
case "m":
|
case "m":
|
||||||
isStashed := m.currentDocument.markdownType == StashedDocument ||
|
isStashed := m.currentDocument.markdownType == StashedDoc ||
|
||||||
m.currentDocument.markdownType == ConvertedDocument
|
m.currentDocument.markdownType == ConvertedDoc
|
||||||
|
|
||||||
// Users can only set the note on user-stashed markdown
|
// Users can only set the note on user-stashed markdown
|
||||||
if !isStashed {
|
if !isStashed {
|
||||||
|
@ -244,7 +244,7 @@ func (m pagerModel) update(msg tea.Msg) (pagerModel, tea.Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stash a local document
|
// Stash a local document
|
||||||
if m.state != pagerStateStashing && m.currentDocument.markdownType == LocalDocument {
|
if m.state != pagerStateStashing && m.currentDocument.markdownType == LocalDoc {
|
||||||
m.state = pagerStateStashing
|
m.state = pagerStateStashing
|
||||||
m.spinner.Start()
|
m.spinner.Start()
|
||||||
cmds = append(
|
cmds = append(
|
||||||
|
@ -348,7 +348,7 @@ func (m pagerModel) statusBarView(b *strings.Builder) {
|
||||||
percentToStringMagnitude float64 = 100.0
|
percentToStringMagnitude float64 = 100.0
|
||||||
)
|
)
|
||||||
var (
|
var (
|
||||||
isStashed bool = m.currentDocument.markdownType == StashedDocument || m.currentDocument.markdownType == ConvertedDocument
|
isStashed bool = m.currentDocument.markdownType == StashedDoc || m.currentDocument.markdownType == ConvertedDoc
|
||||||
showStatusMessage bool = m.state == pagerStateStatusMessage
|
showStatusMessage bool = m.state == pagerStateStatusMessage
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -440,7 +440,7 @@ func (m pagerModel) setNoteView(b *strings.Builder) {
|
||||||
|
|
||||||
func (m pagerModel) helpView() (s string) {
|
func (m pagerModel) helpView() (s string) {
|
||||||
memoOrStash := "m set memo"
|
memoOrStash := "m set memo"
|
||||||
if m.general.authStatus == authOK && m.currentDocument.markdownType == LocalDocument {
|
if m.general.authStatus == authOK && m.currentDocument.markdownType == LocalDoc {
|
||||||
memoOrStash = "s stash this document"
|
memoOrStash = "s stash this document"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,7 +453,7 @@ func (m pagerModel) helpView() (s string) {
|
||||||
"q quit",
|
"q quit",
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.currentDocument.markdownType == NewsDocument {
|
if m.currentDocument.markdownType == NewsDoc {
|
||||||
deleteFromStringSlice(col1, 3)
|
deleteFromStringSlice(col1, 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
70
ui/stash.go
70
ui/stash.go
|
@ -79,7 +79,9 @@ type stashModel struct {
|
||||||
filterInput textinput.Model
|
filterInput textinput.Model
|
||||||
stashFullyLoaded bool // have we loaded all available stashed documents from the server?
|
stashFullyLoaded bool // have we loaded all available stashed documents from the server?
|
||||||
loadingFromNetwork bool // are we currently loading something from the network?
|
loadingFromNetwork bool // are we currently loading something from the network?
|
||||||
loaded DocumentType // load status for news, stash and local files loading; we find out exactly with bitmasking
|
|
||||||
|
// Tracks what exactly is loaded between the stash, news and local files
|
||||||
|
loaded DocTypeSet
|
||||||
|
|
||||||
// The master set of markdown documents we're working with.
|
// The master set of markdown documents we're working with.
|
||||||
markdowns []*markdown
|
markdowns []*markdown
|
||||||
|
@ -114,16 +116,15 @@ type stashModel struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m stashModel) localOnly() bool {
|
func (m stashModel) localOnly() bool {
|
||||||
return m.general.cfg.DocumentTypes^LocalDocument == 0
|
return m.general.cfg.DocumentTypes.Equals(NewDocTypeSet(LocalDoc))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m stashModel) stashedOnly() bool {
|
func (m stashModel) stashedOnly() bool {
|
||||||
return m.general.cfg.DocumentTypes&LocalDocument == 0
|
return m.general.cfg.DocumentTypes.Equals(NewDocTypeSet(StashedDoc))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m stashModel) loadingDone() bool {
|
func (m stashModel) loadingDone() bool {
|
||||||
// Do the types loaded match the types we want to have?
|
return m.loaded.Equals(m.general.cfg.DocumentTypes)
|
||||||
return m.loaded == m.general.cfg.DocumentTypes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether or not we're online. That is, when "local-only" mode is
|
// Returns whether or not we're online. That is, when "local-only" mode is
|
||||||
|
@ -251,7 +252,7 @@ func (m *stashModel) replaceLocalMarkdown(localPath string, newMarkdown *markdow
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the number of markdown documents of a given type.
|
// Return the number of markdown documents of a given type.
|
||||||
func (m stashModel) countMarkdowns(t DocumentType) (found int) {
|
func (m stashModel) countMarkdowns(t DocType) (found int) {
|
||||||
mds := m.getVisibleMarkdowns()
|
mds := m.getVisibleMarkdowns()
|
||||||
if len(mds) == 0 {
|
if len(mds) == 0 {
|
||||||
return
|
return
|
||||||
|
@ -265,7 +266,7 @@ func (m stashModel) countMarkdowns(t DocumentType) (found int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sift through the master markdown collection for the specified types.
|
// Sift through the master markdown collection for the specified types.
|
||||||
func (m stashModel) getMarkdownByType(types ...DocumentType) []*markdown {
|
func (m stashModel) getMarkdownByType(types ...DocType) []*markdown {
|
||||||
var agg []*markdown
|
var agg []*markdown
|
||||||
|
|
||||||
if len(m.markdowns) == 0 {
|
if len(m.markdowns) == 0 {
|
||||||
|
@ -291,19 +292,19 @@ func (m stashModel) getVisibleMarkdowns() []*markdown {
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.state == stashStateShowNews {
|
if m.state == stashStateShowNews {
|
||||||
return m.getMarkdownByType(NewsDocument)
|
return m.getMarkdownByType(NewsDoc)
|
||||||
}
|
}
|
||||||
|
|
||||||
return m.getMarkdownByType(LocalDocument, StashedDocument, ConvertedDocument)
|
return m.getMarkdownByType(LocalDoc, StashedDoc, ConvertedDoc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the markdowns eligible to be filtered.
|
// Return the markdowns eligible to be filtered.
|
||||||
func (m stashModel) getFilterableMarkdowns() []*markdown {
|
func (m stashModel) getFilterableMarkdowns() []*markdown {
|
||||||
if m.state == stashStateShowNews {
|
if m.state == stashStateShowNews {
|
||||||
return m.getMarkdownByType(NewsDocument)
|
return m.getMarkdownByType(NewsDoc)
|
||||||
}
|
}
|
||||||
|
|
||||||
return m.getMarkdownByType(LocalDocument, StashedDocument, ConvertedDocument)
|
return m.getMarkdownByType(LocalDoc, StashedDoc, ConvertedDoc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command for opening a markdown document in the pager. Note that this also
|
// Command for opening a markdown document in the pager. Note that this also
|
||||||
|
@ -312,7 +313,7 @@ func (m *stashModel) openMarkdown(md *markdown) tea.Cmd {
|
||||||
var cmd tea.Cmd
|
var cmd tea.Cmd
|
||||||
m.state = stashStateLoadingDocument
|
m.state = stashStateLoadingDocument
|
||||||
|
|
||||||
if md.markdownType == LocalDocument {
|
if md.markdownType == LocalDoc {
|
||||||
cmd = loadLocalMarkdown(md)
|
cmd = loadLocalMarkdown(md)
|
||||||
} else {
|
} else {
|
||||||
cmd = loadRemoteMarkdown(m.general.cc, md.ID, md.markdownType)
|
cmd = loadRemoteMarkdown(m.general.cc, md.ID, md.markdownType)
|
||||||
|
@ -402,6 +403,7 @@ func newStashModel(general *general) stashModel {
|
||||||
filterInput: si,
|
filterInput: si,
|
||||||
page: 1,
|
page: 1,
|
||||||
paginator: p,
|
paginator: p,
|
||||||
|
loaded: NewDocTypeSet(),
|
||||||
loadingFromNetwork: true,
|
loadingFromNetwork: true,
|
||||||
filesStashing: make(map[string]struct{}),
|
filesStashing: make(map[string]struct{}),
|
||||||
}
|
}
|
||||||
|
@ -420,17 +422,17 @@ func (m stashModel) update(msg tea.Msg) (stashModel, tea.Cmd) {
|
||||||
|
|
||||||
case stashLoadErrMsg:
|
case stashLoadErrMsg:
|
||||||
m.err = msg.err
|
m.err = msg.err
|
||||||
m.loaded |= StashedDocument // still done, albeit unsuccessfully
|
m.loaded.Add(StashedDoc) // still done, albeit unsuccessfully
|
||||||
m.stashFullyLoaded = true
|
m.stashFullyLoaded = true
|
||||||
m.loadingFromNetwork = false
|
m.loadingFromNetwork = false
|
||||||
|
|
||||||
case newsLoadErrMsg:
|
case newsLoadErrMsg:
|
||||||
m.err = msg.err
|
m.err = msg.err
|
||||||
m.loaded |= NewsDocument // still done, albeit unsuccessfully
|
m.loaded.Add(NewsDoc) // still done, albeit unsuccessfully
|
||||||
|
|
||||||
case localFileSearchFinished:
|
case localFileSearchFinished:
|
||||||
// We're finished searching for local files
|
// We're finished searching for local files
|
||||||
m.loaded |= LocalDocument
|
m.loaded.Add(LocalDoc)
|
||||||
|
|
||||||
case gotStashMsg, gotNewsMsg:
|
case gotStashMsg, gotNewsMsg:
|
||||||
// Stash or news results have come in from the server.
|
// Stash or news results have come in from the server.
|
||||||
|
@ -441,9 +443,9 @@ func (m stashModel) update(msg tea.Msg) (stashModel, tea.Cmd) {
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case gotStashMsg:
|
case gotStashMsg:
|
||||||
m.loaded |= StashedDocument
|
m.loaded.Add(StashedDoc)
|
||||||
m.loadingFromNetwork = false
|
m.loadingFromNetwork = false
|
||||||
docs = wrapMarkdowns(StashedDocument, msg)
|
docs = wrapMarkdowns(StashedDoc, msg)
|
||||||
|
|
||||||
if len(msg) == 0 {
|
if len(msg) == 0 {
|
||||||
// If the server comes back with nothing then we've got
|
// If the server comes back with nothing then we've got
|
||||||
|
@ -456,8 +458,8 @@ func (m stashModel) update(msg tea.Msg) (stashModel, tea.Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case gotNewsMsg:
|
case gotNewsMsg:
|
||||||
m.loaded |= NewsDocument
|
m.loaded.Add(NewsDoc)
|
||||||
docs = wrapMarkdowns(NewsDocument, msg)
|
docs = wrapMarkdowns(NewsDoc, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're filtering build filter indexes immediately so any
|
// If we're filtering build filter indexes immediately so any
|
||||||
|
@ -618,7 +620,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
md := m.selectedMarkdown()
|
md := m.selectedMarkdown()
|
||||||
isUserMarkdown := md.markdownType == StashedDocument || md.markdownType == ConvertedDocument
|
isUserMarkdown := md.markdownType == StashedDoc || md.markdownType == ConvertedDoc
|
||||||
isSettingNote := m.selectionState == selectionSettingNote
|
isSettingNote := m.selectionState == selectionSettingNote
|
||||||
isPromptingDelete := m.selectionState == selectionPromptingDelete
|
isPromptingDelete := m.selectionState == selectionPromptingDelete
|
||||||
|
|
||||||
|
@ -659,7 +661,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
|
||||||
md := m.selectedMarkdown()
|
md := m.selectedMarkdown()
|
||||||
|
|
||||||
_, isBeingStashed := m.filesStashing[md.localPath]
|
_, isBeingStashed := m.filesStashing[md.localPath]
|
||||||
isLocalMarkdown := md.markdownType == LocalDocument
|
isLocalMarkdown := md.markdownType == LocalDoc
|
||||||
markdownPathMissing := md.localPath == ""
|
markdownPathMissing := md.localPath == ""
|
||||||
|
|
||||||
if isBeingStashed || !isLocalMarkdown || markdownPathMissing {
|
if isBeingStashed || !isLocalMarkdown || markdownPathMissing {
|
||||||
|
@ -692,7 +694,7 @@ func (m *stashModel) handleDocumentBrowsing(msg tea.Msg) tea.Cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
t := m.selectedMarkdown().markdownType
|
t := m.selectedMarkdown().markdownType
|
||||||
if t == StashedDocument || t == ConvertedDocument {
|
if t == StashedDoc || t == ConvertedDoc {
|
||||||
m.selectionState = selectionPromptingDelete
|
m.selectionState = selectionPromptingDelete
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,10 +759,10 @@ func (m *stashModel) handleDeleteConfirmation(msg tea.Msg) tea.Cmd {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if md.markdownType == ConvertedDocument {
|
if md.markdownType == ConvertedDoc {
|
||||||
// If document was stashed during this session, convert it
|
// If document was stashed during this session, convert it
|
||||||
// back to a local file.
|
// back to a local file.
|
||||||
md.markdownType = LocalDocument
|
md.markdownType = LocalDoc
|
||||||
md.Note = stripAbsolutePath(m.markdowns[i].localPath, m.general.cwd)
|
md.Note = stripAbsolutePath(m.markdowns[i].localPath, m.general.cwd)
|
||||||
} else {
|
} else {
|
||||||
// Delete optimistically and remove the stashed item
|
// Delete optimistically and remove the stashed item
|
||||||
|
@ -995,9 +997,9 @@ func stashHeaderView(m stashModel) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
localItems := m.countMarkdowns(LocalDocument)
|
localItems := m.countMarkdowns(LocalDoc)
|
||||||
stashedItems := m.countMarkdowns(StashedDocument) + m.countMarkdowns(ConvertedDocument)
|
stashedItems := m.countMarkdowns(StashedDoc) + m.countMarkdowns(ConvertedDoc)
|
||||||
newsItems := m.countMarkdowns(NewsDocument)
|
newsItems := m.countMarkdowns(NewsDoc)
|
||||||
|
|
||||||
// Loading's finished and all we have is news.
|
// Loading's finished and all we have is news.
|
||||||
if !loading && localItems == 0 && stashedItems == 0 && newsItems == 0 {
|
if !loading && localItems == 0 && stashedItems == 0 && newsItems == 0 {
|
||||||
|
@ -1076,8 +1078,8 @@ func stashHelpView(m stashModel) string {
|
||||||
|
|
||||||
if numDocs > 0 {
|
if numDocs > 0 {
|
||||||
md := m.selectedMarkdown()
|
md := m.selectedMarkdown()
|
||||||
isStashed = md != nil && md.markdownType == StashedDocument
|
isStashed = md != nil && md.markdownType == StashedDoc
|
||||||
isLocal = md != nil && md.markdownType == LocalDocument
|
isLocal = md != nil && md.markdownType == LocalDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.selectionState == selectionSettingNote {
|
if m.selectionState == selectionSettingNote {
|
||||||
|
@ -1162,14 +1164,14 @@ func stashHelpViewBuilder(windowWidth int, sections ...string) string {
|
||||||
|
|
||||||
// COMMANDS
|
// COMMANDS
|
||||||
|
|
||||||
func loadRemoteMarkdown(cc *charm.Client, id int, t DocumentType) tea.Cmd {
|
func loadRemoteMarkdown(cc *charm.Client, id int, t DocType) tea.Cmd {
|
||||||
return func() tea.Msg {
|
return func() tea.Msg {
|
||||||
var (
|
var (
|
||||||
md *charm.Markdown
|
md *charm.Markdown
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
if t == StashedDocument || t == ConvertedDocument {
|
if t == StashedDoc || t == ConvertedDoc {
|
||||||
md, err = cc.GetStashMarkdown(id)
|
md, err = cc.GetStashMarkdown(id)
|
||||||
} else {
|
} else {
|
||||||
md, err = cc.GetNewsMarkdown(id)
|
md, err = cc.GetNewsMarkdown(id)
|
||||||
|
@ -1191,7 +1193,7 @@ func loadRemoteMarkdown(cc *charm.Client, id int, t DocumentType) tea.Cmd {
|
||||||
|
|
||||||
func loadLocalMarkdown(md *markdown) tea.Cmd {
|
func loadLocalMarkdown(md *markdown) tea.Cmd {
|
||||||
return func() tea.Msg {
|
return func() tea.Msg {
|
||||||
if md.markdownType != LocalDocument {
|
if md.markdownType != LocalDoc {
|
||||||
return errMsg{errors.New("could not load local file: not a local file")}
|
return errMsg{errors.New("could not load local file: not a local file")}
|
||||||
}
|
}
|
||||||
if md.localPath == "" {
|
if md.localPath == "" {
|
||||||
|
@ -1256,11 +1258,11 @@ func deleteMarkdown(markdowns []*markdown, target *markdown) ([]*markdown, error
|
||||||
|
|
||||||
for i, v := range markdowns {
|
for i, v := range markdowns {
|
||||||
switch target.markdownType {
|
switch target.markdownType {
|
||||||
case LocalDocument, ConvertedDocument:
|
case LocalDoc, ConvertedDoc:
|
||||||
if v.localPath == target.localPath {
|
if v.localPath == target.localPath {
|
||||||
index = i
|
index = i
|
||||||
}
|
}
|
||||||
case StashedDocument, NewsDocument:
|
case StashedDoc, NewsDoc:
|
||||||
if v.ID == target.ID {
|
if v.ID == target.ID {
|
||||||
index = i
|
index = i
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,13 @@ func stashItemView(b *strings.Builder, m stashModel, index int, md *markdown) {
|
||||||
)
|
)
|
||||||
|
|
||||||
switch md.markdownType {
|
switch md.markdownType {
|
||||||
case NewsDocument:
|
case NewsDoc:
|
||||||
if title == "" {
|
if title == "" {
|
||||||
title = "News"
|
title = "News"
|
||||||
} else {
|
} else {
|
||||||
title = truncate(title, truncateTo)
|
title = truncate(title, truncateTo)
|
||||||
}
|
}
|
||||||
case StashedDocument, ConvertedDocument:
|
case StashedDoc, ConvertedDoc:
|
||||||
icon = fileListingStashIcon
|
icon = fileListingStashIcon
|
||||||
if title == "" {
|
if title == "" {
|
||||||
title = noMemoTitle
|
title = noMemoTitle
|
||||||
|
@ -80,7 +80,7 @@ func stashItemView(b *strings.Builder, m stashModel, index int, md *markdown) {
|
||||||
} else {
|
} else {
|
||||||
// Regular (non-selected) items
|
// Regular (non-selected) items
|
||||||
|
|
||||||
if md.markdownType == NewsDocument {
|
if md.markdownType == NewsDoc {
|
||||||
gutter = " "
|
gutter = " "
|
||||||
|
|
||||||
if isFiltering && m.filterInput.Value() == "" {
|
if isFiltering && m.filterInput.Value() == "" {
|
||||||
|
|
20
ui/ui.go
20
ui/ui.go
|
@ -41,7 +41,7 @@ type Config struct {
|
||||||
GlamourStyle string
|
GlamourStyle string
|
||||||
|
|
||||||
// Which document types shall we show? We work though this with bitmasking.
|
// Which document types shall we show? We work though this with bitmasking.
|
||||||
DocumentTypes DocumentType
|
DocumentTypes DocTypeSet
|
||||||
|
|
||||||
// For debugging the UI
|
// For debugging the UI
|
||||||
Logfile string `env:"GLOW_LOGFILE"`
|
Logfile string `env:"GLOW_LOGFILE"`
|
||||||
|
@ -189,8 +189,8 @@ func newModel(cfg Config) tea.Model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.DocumentTypes == 0 {
|
if len(cfg.DocumentTypes) == 0 {
|
||||||
cfg.DocumentTypes = LocalDocument | StashedDocument | NewsDocument
|
cfg.DocumentTypes.Add(LocalDoc, StashedDoc, NewsDoc)
|
||||||
}
|
}
|
||||||
|
|
||||||
general := general{
|
general := general{
|
||||||
|
@ -209,16 +209,16 @@ func newModel(cfg Config) tea.Model {
|
||||||
|
|
||||||
func (m model) Init() tea.Cmd {
|
func (m model) Init() tea.Cmd {
|
||||||
var cmds []tea.Cmd
|
var cmds []tea.Cmd
|
||||||
d := &m.general.cfg.DocumentTypes
|
d := m.general.cfg.DocumentTypes
|
||||||
|
|
||||||
if *d&StashedDocument != 0 || *d&NewsDocument != 0 {
|
if d.Contains(StashedDoc) || d.Contains(NewsDoc) {
|
||||||
cmds = append(cmds,
|
cmds = append(cmds,
|
||||||
newCharmClient,
|
newCharmClient,
|
||||||
spinner.Tick,
|
spinner.Tick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *d&LocalDocument != 0 {
|
if d.Contains(LocalDoc) {
|
||||||
cmds = append(cmds, findLocalFiles(m))
|
cmds = append(cmds, findLocalFiles(m))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even though it failed, news/stash loading is finished
|
// Even though it failed, news/stash loading is finished
|
||||||
m.stash.loaded |= StashedDocument | NewsDocument
|
m.stash.loaded.Add(StashedDoc, NewsDoc)
|
||||||
m.stash.loadingFromNetwork = false
|
m.stash.loadingFromNetwork = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
m.keygenState = keygenFinished
|
m.keygenState = keygenFinished
|
||||||
|
|
||||||
// Even though it failed, news/stash loading is finished
|
// Even though it failed, news/stash loading is finished
|
||||||
m.stash.loaded |= StashedDocument | NewsDocument
|
m.stash.loaded.Add(StashedDoc, NewsDoc)
|
||||||
m.stash.loadingFromNetwork = false
|
m.stash.loadingFromNetwork = false
|
||||||
|
|
||||||
case keygenSuccessMsg:
|
case keygenSuccessMsg:
|
||||||
|
@ -636,7 +636,7 @@ func stashDocument(cc *charm.Client, md markdown) tea.Cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turn local markdown into a newly stashed (converted) markdown
|
// Turn local markdown into a newly stashed (converted) markdown
|
||||||
md.markdownType = ConvertedDocument
|
md.markdownType = ConvertedDoc
|
||||||
md.CreatedAt = time.Now()
|
md.CreatedAt = time.Now()
|
||||||
|
|
||||||
// Set the note as the filename without the extension
|
// Set the note as the filename without the extension
|
||||||
|
@ -672,7 +672,7 @@ func waitForStatusMessageTimeout(appCtx applicationContext, t *time.Timer) tea.C
|
||||||
// already done that.
|
// already done that.
|
||||||
func localFileToMarkdown(cwd string, res gitcha.SearchResult) *markdown {
|
func localFileToMarkdown(cwd string, res gitcha.SearchResult) *markdown {
|
||||||
md := &markdown{
|
md := &markdown{
|
||||||
markdownType: LocalDocument,
|
markdownType: LocalDoc,
|
||||||
localPath: res.Path,
|
localPath: res.Path,
|
||||||
Markdown: charm.Markdown{
|
Markdown: charm.Markdown{
|
||||||
Note: stripAbsolutePath(res.Path, cwd),
|
Note: stripAbsolutePath(res.Path, cwd),
|
||||||
|
|
Loading…
Reference in a new issue