From a960418c37e95a9c497f4a95597cb7efcbd517dd Mon Sep 17 00:00:00 2001 From: Robby Date: Sat, 9 Dec 2023 22:05:11 -0500 Subject: [PATCH 1/7] Add `--tui` Flag --- main.go | 40 +++++++++++++++++++++++++++++++++++++++- ui/config.go | 6 ++++++ ui/ui.go | 42 +++++++++++++++++++++++++++++++++++------- 3 files changed, 80 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 86a089cb..c83ebf93 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,7 @@ import ( "os/exec" "path/filepath" "strings" + "time" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/glamour" @@ -31,6 +32,7 @@ var ( readmeNames = []string{"README.md", "README"} configFile string pager bool + tui bool style string width uint showAllFiles bool @@ -140,6 +142,7 @@ func validateOptions(cmd *cobra.Command) error { localOnly = viper.GetBool("local") mouse = viper.GetBool("mouse") pager = viper.GetBool("pager") + tui = viper.GetBool("tui") // validate the glamour style style = viper.GetString("style") @@ -219,6 +222,16 @@ func execute(cmd *cobra.Command, args []string) error { return runTUI(p, false) } } + + useTUI := tui || cmd.Flags().Changed("tui") + if err == nil && useTUI && !info.IsDir() { + // Is file; open in TUI-mode + p, err := filepath.Abs(args[0]) + if err == nil { + return runTUI(p, false, true) + } + } + fallthrough // CLI @@ -313,7 +326,29 @@ func executeCLI(cmd *cobra.Command, src *source, w io.Writer) error { return nil } -func runTUI(workingDirectory string, stashedOnly bool) error { +func runTUI(path string, stashedOnly bool, withFile ...bool) error { + var ( + workingDirectory string + filePath string + createdAt time.Time + ) + + if len(withFile) == 1 && withFile[0] == true { + // Open TUI-mode with file + workingDirectory = filepath.Dir(path) + filePath = path + fileInfo, err := os.Stat(filePath) + if err != nil { + createdAt = time.Now() + } else { + createdAt = fileInfo.ModTime() + } + } else { + workingDirectory = path + filePath = "" + createdAt = time.Now() + } + // Read environment to get debugging stuff var cfg ui.Config if err := babyenv.Parse(&cfg); err != nil { @@ -330,6 +365,8 @@ func runTUI(workingDirectory string, stashedOnly bool) error { } cfg.WorkingDirectory = workingDirectory + cfg.FilePath = filePath + cfg.FileCreatedAt = createdAt cfg.DocumentTypes = ui.NewDocTypeSet() cfg.ShowAllFiles = showAllFiles cfg.GlamourMaxWidth = width @@ -372,6 +409,7 @@ func init() { // "Glow Classic" cli arguments rootCmd.PersistentFlags().StringVar(&configFile, "config", "", fmt.Sprintf("config file (default %s)", defaultConfigFile)) rootCmd.Flags().BoolVarP(&pager, "pager", "p", false, "display with pager") + rootCmd.Flags().BoolVarP(&tui, "tui", "t", false, "display with TUI-mode") rootCmd.Flags().StringVarP(&style, "style", "s", "auto", "style name or JSON path") rootCmd.Flags().UintVarP(&width, "width", "w", 0, "word-wrap at width") rootCmd.Flags().BoolVarP(&showAllFiles, "all", "a", false, "show system files and directories (TUI-mode only)") diff --git a/ui/config.go b/ui/config.go index 9db23406..516b7fe0 100644 --- a/ui/config.go +++ b/ui/config.go @@ -1,5 +1,7 @@ package ui +import "time" + // Config contains TUI-specific configuration. type Config struct { ShowAllFiles bool @@ -12,6 +14,10 @@ type Config struct { // Which directory should we start from? WorkingDirectory string + // (Optional) If not "", open TUI-mode with this file open + FilePath string + FileCreatedAt time.Time + // Which document types shall we show? DocumentTypes DocTypeSet diff --git a/ui/ui.go b/ui/ui.go index df7e37f8..20a20311 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -53,12 +53,19 @@ func NewProgram(cfg Config) *tea.Program { log.Println("Bubble Tea now initializing...") debug = true } + config = cfg + opts := []tea.ProgramOption{tea.WithAltScreen()} if cfg.EnableMouse { opts = append(opts, tea.WithMouseCellMotion()) } - return tea.NewProgram(newModel(cfg), opts...) + + m := newModel(cfg) + + program := tea.NewProgram(m, opts...) + + return program } type errMsg struct{ err error } @@ -220,13 +227,22 @@ func newModel(cfg Config) tea.Model { filesStashing: make(map[ksuid.KSUID]struct{}), } - return model{ + m := model{ common: &common, state: stateShowStash, keygenState: keygenUnstarted, pager: newPagerModel(&common), stash: newStashModel(&common), } + + if cfg.FilePath != "" { + // Open file passed in with TUI-mode flag + m.pager.currentDocument = *localFileToMarkdown(cfg.WorkingDirectory, cfg.FilePath, cfg.FileCreatedAt, true) // TODO: Fix time + m.state = stateShowDocument + m.pager.update(keyEnter) + } + + return m } func (m model) Init() tea.Cmd { @@ -359,6 +375,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case fetchedMarkdownMsg: // We've loaded a markdown file's contents for rendering + println("Update markdown!") m.pager.currentDocument = *msg msg.Body = string(utils.RemoveFrontmatter([]byte(msg.Body))) cmds = append(cmds, renderWithGlamour(m.pager, msg.Body)) @@ -383,7 +400,8 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, cmd case foundLocalFileMsg: - newMd := localFileToMarkdown(m.common.cwd, gitcha.SearchResult(msg)) + res := gitcha.SearchResult(msg) + newMd := localFileToMarkdown(m.common.cwd, res.Path, res.Info.ModTime()) m.stash.addMarkdowns(newMd) if m.stash.filterApplied() { newMd.buildFilterValue() @@ -723,13 +741,23 @@ func waitForStatusMessageTimeout(appCtx applicationContext, t *time.Timer) tea.C // Convert a Gitcha result to an internal representation of a markdown // document. Note that we could be doing things like checking if the file is // a directory, but we trust that gitcha has already done that. -func localFileToMarkdown(cwd string, res gitcha.SearchResult) *markdown { +func localFileToMarkdown(cwd string, path string, createdAt time.Time, loadBody ...bool) *markdown { + body := "" + if len(loadBody) == 1 && loadBody[0] { + content, err := os.ReadFile(path) + if err == nil { + // Convert the byte slice to a string + body = string(content) + } + } + md := &markdown{ docType: LocalDoc, - localPath: res.Path, + localPath: path, Markdown: charm.Markdown{ - Note: stripAbsolutePath(res.Path, cwd), - CreatedAt: res.Info.ModTime(), + Body: body, + Note: stripAbsolutePath(path, cwd), + CreatedAt: createdAt, }, } From 170bdc66f269a07a0f48de24199888e5ae09ca78 Mon Sep 17 00:00:00 2001 From: Robby Date: Sun, 10 Dec 2023 11:27:04 -0500 Subject: [PATCH 2/7] Remove println --- ui/ui.go | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/ui.go b/ui/ui.go index 20a20311..aded33d0 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -375,7 +375,6 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case fetchedMarkdownMsg: // We've loaded a markdown file's contents for rendering - println("Update markdown!") m.pager.currentDocument = *msg msg.Body = string(utils.RemoveFrontmatter([]byte(msg.Body))) cmds = append(cmds, renderWithGlamour(m.pager, msg.Body)) From b14192467ca7c3ca02eb8152ae62b764f2a362f2 Mon Sep 17 00:00:00 2001 From: Robby Date: Tue, 23 Jan 2024 19:53:37 -0500 Subject: [PATCH 3/7] Update `charmbracelet/x` --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f72ce9c3..8e7f2eee 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/charmbracelet/charm v0.8.7 github.com/charmbracelet/glamour v0.6.0 github.com/charmbracelet/lipgloss v0.6.0 - github.com/charmbracelet/x/editor v0.0.0-20231116172829-450eedbca1ab + github.com/charmbracelet/x/editor v0.0.0-20240118113134-7c8cecb18fdb github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac github.com/mattn/go-runewidth v0.0.14 github.com/meowgorithm/babyenv v1.3.1 diff --git a/go.sum b/go.sum index 96ccc7d5..7bccef04 100644 --- a/go.sum +++ b/go.sum @@ -234,8 +234,8 @@ github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8o github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v0.6.0 h1:1StyZB9vBSOyuZxQUcUwGr17JmojPNm87inij9N3wJY= github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk= -github.com/charmbracelet/x/editor v0.0.0-20231116172829-450eedbca1ab h1:95WbogoQheYFuAUy1olU8OgxrHk2K86zA7mSNELiMfU= -github.com/charmbracelet/x/editor v0.0.0-20231116172829-450eedbca1ab/go.mod h1:lrin7iXW742pX5pePBEWhLPDTp53YW15r/Lp4Rcfg0M= +github.com/charmbracelet/x/editor v0.0.0-20240118113134-7c8cecb18fdb h1:DkWxIrfPV/8pBiZhxUJT22Z1vMLl/ChsMVh14Qe2Mt0= +github.com/charmbracelet/x/editor v0.0.0-20240118113134-7c8cecb18fdb/go.mod h1:oivrEbcP/AYt/Hpvk5pwDXXrQ933gQS6UzL6fxqAGSA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= From db5b0f3e7bf476683caf4198e25374fd865cb057 Mon Sep 17 00:00:00 2001 From: Robby Date: Tue, 23 Jan 2024 19:54:20 -0500 Subject: [PATCH 4/7] Add `OpenAtLine` functionality --- ui/editor.go | 14 +++++++++++--- ui/pager.go | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ui/editor.go b/ui/editor.go index ff094fce..08873e0b 100644 --- a/ui/editor.go +++ b/ui/editor.go @@ -1,22 +1,30 @@ package ui import ( + "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/x/editor" ) type editorFinishedMsg struct{ err error } -func openEditor(path string) tea.Cmd { +func openEditor(path string, viewport_optional ...*viewport.Model) tea.Cmd { + var lineNumber uint = 0 + if len(viewport_optional) == 1 { + vp := viewport_optional[0] + lineNumber = uint(vp.YOffset + vp.Height) + } + cb := func(err error) tea.Msg { return editorFinishedMsg{err} } - editor, err := editor.Cmd("Glow", path) + editorCmd, err := editor.Cmd("Glow", path, editor.OpenAtLine(lineNumber)) if err != nil { return func() tea.Msg { return errMsg{err} } } - return tea.ExecProcess(editor, cb) + + return tea.ExecProcess(editorCmd, cb) } diff --git a/ui/pager.go b/ui/pager.go index 95f6025b..0b398b1d 100644 --- a/ui/pager.go +++ b/ui/pager.go @@ -287,7 +287,7 @@ func (m pagerModel) update(msg tea.Msg) (pagerModel, tea.Cmd) { case "e": if m.currentDocument.docType == LocalDoc { - return m, openEditor(m.currentDocument.localPath) + return m, openEditor(m.currentDocument.localPath, &m.viewport) } case "c": From 8614577ec337f4b7ab533ba892e929a268b39f06 Mon Sep 17 00:00:00 2001 From: Robby Date: Sat, 27 Jan 2024 12:09:20 -0500 Subject: [PATCH 5/7] Update pager after update --- ui/ui.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/ui.go b/ui/ui.go index aded33d0..8b004e42 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -239,7 +239,8 @@ func newModel(cfg Config) tea.Model { // Open file passed in with TUI-mode flag m.pager.currentDocument = *localFileToMarkdown(cfg.WorkingDirectory, cfg.FilePath, cfg.FileCreatedAt, true) // TODO: Fix time m.state = stateShowDocument - m.pager.update(keyEnter) + newPagerModel, _ := m.pager.update(keyEnter) + m.pager = newPagerModel } return m From effd7d70be2f0671eecbeb00e616948e710a9bf8 Mon Sep 17 00:00:00 2001 From: Robby Date: Mon, 29 Jan 2024 18:42:15 -0500 Subject: [PATCH 6/7] Update `x/editor` --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 8e7f2eee..46a0a95c 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/charmbracelet/charm v0.8.7 github.com/charmbracelet/glamour v0.6.0 github.com/charmbracelet/lipgloss v0.6.0 - github.com/charmbracelet/x/editor v0.0.0-20240118113134-7c8cecb18fdb + github.com/charmbracelet/x/editor v0.0.0-20240129143450-0ee713645824 github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac github.com/mattn/go-runewidth v0.0.14 github.com/meowgorithm/babyenv v1.3.1 diff --git a/go.sum b/go.sum index 7bccef04..e9cea423 100644 --- a/go.sum +++ b/go.sum @@ -236,6 +236,8 @@ github.com/charmbracelet/lipgloss v0.6.0 h1:1StyZB9vBSOyuZxQUcUwGr17JmojPNm87ini github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk= github.com/charmbracelet/x/editor v0.0.0-20240118113134-7c8cecb18fdb h1:DkWxIrfPV/8pBiZhxUJT22Z1vMLl/ChsMVh14Qe2Mt0= github.com/charmbracelet/x/editor v0.0.0-20240118113134-7c8cecb18fdb/go.mod h1:oivrEbcP/AYt/Hpvk5pwDXXrQ933gQS6UzL6fxqAGSA= +github.com/charmbracelet/x/editor v0.0.0-20240129143450-0ee713645824 h1:I+fJNplA3CQZe0Sc9+1SrEu+RZjZcrtYWPWlqUnMSko= +github.com/charmbracelet/x/editor v0.0.0-20240129143450-0ee713645824/go.mod h1:oivrEbcP/AYt/Hpvk5pwDXXrQ933gQS6UzL6fxqAGSA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= From dad3e2e265620827012cb7235e494b20ebd54013 Mon Sep 17 00:00:00 2001 From: Robby Date: Sun, 3 Mar 2024 13:03:04 -0500 Subject: [PATCH 7/7] `go mod tidy` --- go.sum | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/go.sum b/go.sum index 6638ee72..0606ce69 100644 --- a/go.sum +++ b/go.sum @@ -235,8 +235,6 @@ github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8o github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v0.6.0 h1:1StyZB9vBSOyuZxQUcUwGr17JmojPNm87inij9N3wJY= github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk= -github.com/charmbracelet/x/editor v0.0.0-20240118113134-7c8cecb18fdb h1:DkWxIrfPV/8pBiZhxUJT22Z1vMLl/ChsMVh14Qe2Mt0= -github.com/charmbracelet/x/editor v0.0.0-20240118113134-7c8cecb18fdb/go.mod h1:oivrEbcP/AYt/Hpvk5pwDXXrQ933gQS6UzL6fxqAGSA= github.com/charmbracelet/x/editor v0.0.0-20240129143450-0ee713645824 h1:I+fJNplA3CQZe0Sc9+1SrEu+RZjZcrtYWPWlqUnMSko= github.com/charmbracelet/x/editor v0.0.0-20240129143450-0ee713645824/go.mod h1:oivrEbcP/AYt/Hpvk5pwDXXrQ933gQS6UzL6fxqAGSA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -277,8 +275,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac h1:opbrjaN/L8gg6Xh5D04Tem+8xVcz6ajZlGCs49mQgyg= +github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -507,9 +505,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/meowgorithm/babyenv v1.3.0/go.mod h1:lwNX+J6AGBFqNrMZ2PTLkM6SO+W4X8DOg9zBDO4j3Ig= github.com/meowgorithm/babyenv v1.3.1 h1:18ZEYIgbzoFQfRLF9+lxjRfk/ui6w8U0FWl07CgWvvc=