Detailed changes
@@ -28,8 +28,6 @@ type RepoCommit struct {
type CommitLog []RepoCommit
-type ReadmeTransform func(string) string
-
func (cl CommitLog) Len() int { return len(cl) }
func (cl CommitLog) Swap(i, j int) { cl[i], cl[j] = cl[j], cl[i] }
func (cl CommitLog) Less(i, j int) bool {
@@ -37,19 +35,18 @@ func (cl CommitLog) Less(i, j int) bool {
}
type RepoSource struct {
- Path string
- mtx sync.Mutex
- repos []*Repo
- commits CommitLog
- readmeTransform ReadmeTransform
+ Path string
+ mtx sync.Mutex
+ repos []*Repo
+ commits CommitLog
}
-func NewRepoSource(repoPath string, rf ReadmeTransform) *RepoSource {
+func NewRepoSource(repoPath string) *RepoSource {
err := os.MkdirAll(repoPath, os.ModeDir|os.FileMode(0700))
if err != nil {
log.Fatal(err)
}
- rs := &RepoSource{Path: repoPath, readmeTransform: rf}
+ rs := &RepoSource{Path: repoPath}
return rs
}
@@ -129,7 +126,7 @@ func (rs *RepoSource) loadRepo(name string, rg *git.Repository) (*Repo, error) {
if err == nil {
rmd, err := rf.Contents()
if err == nil {
- r.Readme = rs.readmeTransform(rmd)
+ r.Readme = rmd
}
}
}
@@ -9,9 +9,7 @@ import (
"smoothie/tui/bubbles/selection"
"time"
- "github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/glamour"
"github.com/charmbracelet/lipgloss"
"github.com/gliderlabs/ssh"
)
@@ -28,6 +26,7 @@ const (
type MenuEntry struct {
Name string `json:"name"`
+ Note string `json:"note"`
Repo string `json:"repo"`
}
@@ -45,20 +44,19 @@ type SessionConfig struct {
}
type Bubble struct {
- config *Config
- state sessionState
- error string
- width int
- height int
- windowChanges <-chan ssh.Window
- repoSource *git.RepoSource
- repoMenu []MenuEntry
- repos []*git.Repo
- boxes []tea.Model
- activeBox int
- repoSelect *selection.Bubble
- commitsLog *commits.Bubble
- readmeViewport *ViewportBubble
+ config *Config
+ state sessionState
+ error string
+ width int
+ height int
+ windowChanges <-chan ssh.Window
+ repoSource *git.RepoSource
+ repoMenu []MenuEntry
+ repos []*git.Repo
+ boxes []tea.Model
+ activeBox int
+ repoSelect *selection.Bubble
+ commitsLog *commits.Bubble
}
func NewBubble(cfg *Config, sCfg *SessionConfig) *Bubble {
@@ -69,12 +67,6 @@ func NewBubble(cfg *Config, sCfg *SessionConfig) *Bubble {
windowChanges: sCfg.WindowChanges,
repoSource: cfg.RepoSource,
boxes: make([]tea.Model, 2),
- readmeViewport: &ViewportBubble{
- Viewport: &viewport.Model{
- Width: boxRightWidth - horizontalPadding - 2,
- Height: sCfg.Height - verticalPadding - viewportHeightConstant,
- },
- },
}
b.state = startState
return b
@@ -149,21 +141,6 @@ func (b *Bubble) View() string {
return appBoxStyle.Render(content)
}
-func glamourReadme(md string) string {
- tr, err := glamour.NewTermRenderer(
- glamour.WithAutoStyle(),
- glamour.WithWordWrap(boxRightWidth-2),
- )
- if err != nil {
- log.Fatal(err)
- }
- mdt, err := tr.Render(md)
- if err != nil {
- return md
- }
- return mdt
-}
-
func loadConfig(rs *git.RepoSource) (*Config, error) {
cfg := &Config{}
cfg.RepoSource = rs
@@ -183,7 +160,7 @@ func loadConfig(rs *git.RepoSource) (*Config, error) {
}
func SessionHandler(reposPath string, repoPoll time.Duration) func(ssh.Session) (tea.Model, []tea.ProgramOption) {
- rs := git.NewRepoSource(reposPath, glamourReadme)
+ rs := git.NewRepoSource(reposPath)
err := createDefaultConfigRepo(rs)
if err != nil {
if err != nil {
@@ -1,22 +1,95 @@
package repo
import (
+ "bytes"
+ "smoothie/git"
+ "text/template"
+
+ "github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
- "github.com/go-git/go-git/v5"
+ "github.com/charmbracelet/glamour"
)
+type ErrMsg struct {
+ Error error
+}
+
type Bubble struct {
- repo *git.Repository
+ templateObject interface{}
+ repoSource *git.RepoSource
+ name string
+ repo *git.Repo
+ readmeViewport *ViewportBubble
+}
+
+func NewBubble(rs *git.RepoSource, name string, width int, height int, tmp interface{}) *Bubble {
+ return &Bubble{
+ templateObject: tmp,
+ repoSource: rs,
+ name: name,
+ readmeViewport: &ViewportBubble{
+ Viewport: &viewport.Model{
+ Width: width,
+ Height: height,
+ },
+ },
+ }
}
func (b *Bubble) Init() tea.Cmd {
- return nil
+ return b.setupCmd
}
-func (b *Bubble) Update(tea.Msg) (tea.Model, tea.Cmd) {
- return nil, nil
+func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ return b.readmeViewport.Update(msg)
}
func (b *Bubble) View() string {
- return "repo"
+ return b.readmeViewport.View()
+}
+
+func (b *Bubble) setupCmd() tea.Msg {
+ r, err := b.repoSource.GetRepo(b.name)
+ if err != nil {
+ return ErrMsg{err}
+ }
+ md := r.Readme
+ if b.templateObject != nil {
+ t, err := template.New("readme").Parse(md)
+ if err != nil {
+ return ErrMsg{err}
+ }
+ buf := &bytes.Buffer{}
+ err = t.Execute(buf, b.templateObject)
+ if err != nil {
+ return ErrMsg{err}
+ }
+ md = buf.String()
+ }
+ md, err = b.glamourize(md)
+ if err != nil {
+ return ErrMsg{err}
+ }
+ b.readmeViewport.Viewport.GotoTop()
+ b.readmeViewport.Viewport.SetContent(md)
+ return nil
+}
+
+func (b *Bubble) templatize(t string) (string, error) {
+ return "", nil
+}
+
+func (b *Bubble) glamourize(md string) (string, error) {
+ tr, err := glamour.NewTermRenderer(
+ glamour.WithAutoStyle(),
+ glamour.WithWordWrap(b.readmeViewport.Viewport.Width),
+ )
+ if err != nil {
+ return "", err
+ }
+ mdt, err := tr.Render(md)
+ if err != nil {
+ return "", err
+ }
+ return mdt, nil
}
@@ -1,4 +1,4 @@
-package tui
+package repo
import (
"github.com/charmbracelet/bubbles/viewport"
@@ -2,6 +2,7 @@ package tui
import (
"smoothie/tui/bubbles/commits"
+ "smoothie/tui/bubbles/repo"
"smoothie/tui/bubbles/selection"
tea "github.com/charmbracelet/bubbletea"
@@ -57,16 +58,13 @@ func (b *Bubble) loadGitCmd() tea.Msg {
}
func (b *Bubble) getRepoCmd(name string) tea.Cmd {
- return func() tea.Msg {
- r, err := b.repoSource.GetRepo(name)
- if err != nil {
- return errMsg{err}
- }
- b.readmeViewport.Viewport.GotoTop()
- b.readmeViewport.Viewport.Height = b.height - verticalPadding - viewportHeightConstant
- b.readmeViewport.Viewport.Width = boxLeftWidth - 2
- b.readmeViewport.Viewport.SetContent(r.Readme)
- b.boxes[1] = b.readmeViewport
- return nil
+ var tmplConfig *Config
+ if name == "config" {
+ tmplConfig = b.config
}
+ h := b.height - verticalPadding - viewportHeightConstant
+ w := boxRightWidth - 2
+ rb := repo.NewBubble(b.repoSource, name, w, h, tmplConfig)
+ b.boxes[1] = rb
+ return rb.Init()
}
@@ -17,7 +17,8 @@ const defaultConfig = `{
"menu": [
{
"name": "Home",
- "repo": "config"
+ "repo": "config",
+ "note": "Configuration and content repo"
}
]
}`