From 99a1fa9d8e8af227e6a7eafcd6c35067941b5369 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Mon, 1 May 2023 09:59:13 -0400 Subject: [PATCH 01/22] chore(deps): update bubbles --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 54a0873..8c0b11e 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/alecthomas/kong v0.7.1 github.com/alecthomas/mango-kong v0.1.0 - github.com/charmbracelet/bubbles v0.15.1-0.20230324185713-1de5816ab4f7 + github.com/charmbracelet/bubbles v0.15.1-0.20230501135844-7590e13c2a27 github.com/charmbracelet/bubbletea v0.23.3-0.20230316100943-248eb83001a7 github.com/charmbracelet/glamour v0.6.0 github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707 diff --git a/go.sum b/go.sum index 1954741..9fab4ad 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuP github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/charmbracelet/bubbles v0.15.1-0.20230324185713-1de5816ab4f7 h1:16QEZgcSr80fcXZBlqSZG5F+1j5CATd/ZLcNjV8DBdU= github.com/charmbracelet/bubbles v0.15.1-0.20230324185713-1de5816ab4f7/go.mod h1:39HL8bnL0foloiENA/KvD+3mNg5SqWQV2Qh3eY/4ey4= +github.com/charmbracelet/bubbles v0.15.1-0.20230501135844-7590e13c2a27 h1:IF1XCxwu1M1J+n+akXYUm4CQh1B+2QdZxhJEW4G0kG0= +github.com/charmbracelet/bubbles v0.15.1-0.20230501135844-7590e13c2a27/go.mod h1:39HL8bnL0foloiENA/KvD+3mNg5SqWQV2Qh3eY/4ey4= github.com/charmbracelet/bubbletea v0.23.1/go.mod h1:JAfGK/3/pPKHTnAS8JIE2u9f61BjWTQY57RbT25aMXU= github.com/charmbracelet/bubbletea v0.23.3-0.20230316100943-248eb83001a7 h1:QWRijV4kfijpili/tRA9FAxS1Pw1B2n4+RF2UVOmBbw= github.com/charmbracelet/bubbletea v0.23.3-0.20230316100943-248eb83001a7/go.mod h1:/9VgEZjOAyBTwlaj5ILlkrpeuulz+b2ITKJNKo/5vK0= From 39346ed01566675476dd89b158984a771cd05acf Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Mon, 1 May 2023 13:47:07 +0000 Subject: [PATCH 02/22] fix: missing filepicker styles Signed-off-by: Carlos Alexandro Becker --- file/command.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/file/command.go b/file/command.go index 3cf93b5..71c1b79 100644 --- a/file/command.go +++ b/file/command.go @@ -37,15 +37,14 @@ func (o Options) Run() error { fp.DirAllowed = o.Directory fp.FileAllowed = o.File fp.ShowHidden = o.All - fp.Styles = filepicker.Styles{ - Cursor: o.CursorStyle.ToLipgloss(), - Symlink: o.SymlinkStyle.ToLipgloss(), - Directory: o.DirectoryStyle.ToLipgloss(), - File: o.FileStyle.ToLipgloss(), - Permission: o.PermissionsStyle.ToLipgloss(), - Selected: o.SelectedStyle.ToLipgloss(), - FileSize: o.FileSizeStyle.ToLipgloss(), - } + fp.Styles = filepicker.DefaultStyles + fp.Styles.Cursor = o.CursorStyle.ToLipgloss() + fp.Styles.Symlink = o.SymlinkStyle.ToLipgloss() + fp.Styles.Directory = o.DirectoryStyle.ToLipgloss() + fp.Styles.File = o.FileStyle.ToLipgloss() + fp.Styles.Permission = o.PermissionsStyle.ToLipgloss() + fp.Styles.Selected = o.SelectedStyle.ToLipgloss() + fp.Styles.FileSize = o.FileSizeStyle.ToLipgloss() m := model{filepicker: fp} From fff07286b79bf4fd59c2d72849345e2c8fc875bd Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Thu, 11 May 2023 12:39:14 +0000 Subject: [PATCH 03/22] docs: update license Signed-off-by: Carlos Alexandro Becker --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index ece3536..6f5b1fa 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Charmbracelet, Inc +Copyright (c) 2021-2023 Charmbracelet, Inc Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 11584b598229786d0261d441ae7b66ca05e63e84 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Thu, 11 May 2023 11:55:06 -0400 Subject: [PATCH 04/22] chore(docs): correct release year in license --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 6f5b1fa..3d2e904 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2023 Charmbracelet, Inc +Copyright (c) 2022-2023 Charmbracelet, Inc Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 7f54b3b28921f912274e01d39a9902177a9dd74f Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Thu, 11 May 2023 14:04:39 -0400 Subject: [PATCH 05/22] feat(write): width < 1 uses terminal width --- input/command.go | 1 + input/input.go | 6 ++++++ input/options.go | 2 +- write/command.go | 1 + write/options.go | 2 +- write/write.go | 5 +++++ 6 files changed, 15 insertions(+), 2 deletions(-) diff --git a/input/command.go b/input/command.go index ec6f20e..c15e180 100644 --- a/input/command.go +++ b/input/command.go @@ -41,6 +41,7 @@ func (o Options) Run() error { aborted: false, header: o.Header, headerStyle: o.HeaderStyle.ToLipgloss(), + autoWidth: o.Width < 1, }, tea.WithOutput(os.Stderr)) tm, err := p.Run() if err != nil { diff --git a/input/input.go b/input/input.go index 5b0cae1..fbc84c5 100644 --- a/input/input.go +++ b/input/input.go @@ -11,9 +11,11 @@ import ( "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + "github.com/mattn/go-runewidth" ) type model struct { + autoWidth bool header string headerStyle lipgloss.Style textinput textinput.Model @@ -37,6 +39,10 @@ func (m model) View() string { func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { + case tea.WindowSizeMsg: + if m.autoWidth { + m.textinput.Width = msg.Width - runewidth.StringWidth(m.textinput.Prompt) - 1 + } case tea.KeyMsg: switch msg.String() { case "ctrl+c", "esc": diff --git a/input/options.go b/input/options.go index 2e103f8..86eef6a 100644 --- a/input/options.go +++ b/input/options.go @@ -10,7 +10,7 @@ type Options struct { CursorStyle style.Styles `embed:"" prefix:"cursor." set:"defaultForeground=212" envprefix:"GUM_INPUT_CURSOR_"` Value string `help:"Initial value (can also be passed via stdin)" default:""` CharLimit int `help:"Maximum value length (0 for no limit)" default:"400"` - Width int `help:"Input width" default:"40" env:"GUM_INPUT_WIDTH"` + Width int `help:"Input width (0 for terminal width)" default:"40" env:"GUM_INPUT_WIDTH"` Password bool `help:"Mask input characters" default:"false"` Header string `help:"Header value" default:"" env:"GUM_INPUT_HEADER"` HeaderStyle style.Styles `embed:"" prefix:"header." set:"defaultForeground=240" envprefix:"GUM_INPUT_HEADER_"` diff --git a/write/command.go b/write/command.go index 2177561..84fcd76 100644 --- a/write/command.go +++ b/write/command.go @@ -52,6 +52,7 @@ func (o Options) Run() error { textarea: a, header: o.Header, headerStyle: o.HeaderStyle.ToLipgloss(), + autoWidth: o.Width < 1, }, tea.WithOutput(os.Stderr)) tm, err := p.Run() if err != nil { diff --git a/write/options.go b/write/options.go index 59eb5c0..cfae3c9 100644 --- a/write/options.go +++ b/write/options.go @@ -4,7 +4,7 @@ import "github.com/charmbracelet/gum/style" // Options are the customization options for the textarea. type Options struct { - Width int `help:"Text area width" default:"50" env:"GUM_WRITE_WIDTH"` + Width int `help:"Text area width (0 for terminal width)" default:"50" env:"GUM_WRITE_WIDTH"` Height int `help:"Text area height" default:"5" env:"GUM_WRITE_HEIGHT"` Header string `help:"Header value" default:"" env:"GUM_WRITE_HEADER"` Placeholder string `help:"Placeholder value" default:"Write something..." env:"GUM_WRITE_PLACEHOLDER"` diff --git a/write/write.go b/write/write.go index 2e15415..674b66d 100644 --- a/write/write.go +++ b/write/write.go @@ -15,6 +15,7 @@ import ( ) type model struct { + autoWidth bool aborted bool header string headerStyle lipgloss.Style @@ -39,6 +40,10 @@ func (m model) View() string { func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { + case tea.WindowSizeMsg: + if m.autoWidth { + m.textarea.SetWidth(msg.Width) + } case tea.KeyMsg: switch msg.String() { case "ctrl+c", "esc": From 9d2741c5f91ee9bd346a01f3ce63051fb76d526b Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Thu, 11 May 2023 20:56:39 -0400 Subject: [PATCH 06/22] fix: update copyrights --- man/command.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/command.go b/man/command.go index bfb5c2d..f563af9 100644 --- a/man/command.go +++ b/man/command.go @@ -16,7 +16,7 @@ func (m Man) BeforeApply(ctx *kong.Context) error { // Set the correct man pages description without color escape sequences. ctx.Model.Help = "A tool for glamorous shell scripts." man := mangokong.NewManPage(1, ctx.Model) - man = man.WithSection("Copyright", "(C) 2021-2022 Charmbracelet, Inc.\n"+ + man = man.WithSection("Copyright", "(C) 2021-2023 Charmbracelet, Inc.\n"+ "Released under MIT license.") fmt.Fprint(ctx.Stdout, man.Build(roff.NewDocument())) ctx.Exit(0) From ece25c77895467d5300c2d690e3e6ff71ca85c5d Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Thu, 11 May 2023 21:14:22 -0400 Subject: [PATCH 07/22] fix: correct copyright in man --- man/command.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/command.go b/man/command.go index f563af9..28280ea 100644 --- a/man/command.go +++ b/man/command.go @@ -16,7 +16,7 @@ func (m Man) BeforeApply(ctx *kong.Context) error { // Set the correct man pages description without color escape sequences. ctx.Model.Help = "A tool for glamorous shell scripts." man := mangokong.NewManPage(1, ctx.Model) - man = man.WithSection("Copyright", "(C) 2021-2023 Charmbracelet, Inc.\n"+ + man = man.WithSection("Copyright", "(C) 2022-2023 Charmbracelet, Inc.\n"+ "Released under MIT license.") fmt.Fprint(ctx.Stdout, man.Build(roff.NewDocument())) ctx.Exit(0) From 92c890e71726188271b82c9511feb9ca87ffc208 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Thu, 11 May 2023 22:21:09 -0400 Subject: [PATCH 08/22] fix: use `lipgloss.Width` instead of `runewidth.StringWidth` --- choose/choose.go | 3 +-- filter/filter.go | 3 +-- input/input.go | 3 +-- table/command.go | 4 ++-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/choose/choose.go b/choose/choose.go index 4bd3937..a694a7a 100644 --- a/choose/choose.go +++ b/choose/choose.go @@ -16,7 +16,6 @@ import ( "github.com/charmbracelet/bubbles/paginator" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - "github.com/mattn/go-runewidth" ) type model struct { @@ -158,7 +157,7 @@ func (m model) View() string { if i == m.index%m.height { s.WriteString(m.cursorStyle.Render(m.cursor)) } else { - s.WriteString(strings.Repeat(" ", runewidth.StringWidth(m.cursor))) + s.WriteString(strings.Repeat(" ", lipgloss.Width(m.cursor))) } if item.selected { diff --git a/filter/filter.go b/filter/filter.go index 579c523..54df59e 100644 --- a/filter/filter.go +++ b/filter/filter.go @@ -17,7 +17,6 @@ import ( "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - "github.com/mattn/go-runewidth" "github.com/sahilm/fuzzy" ) @@ -77,7 +76,7 @@ func (m model) View() string { if i == m.cursor { s.WriteString(m.indicatorStyle.Render(m.indicator)) } else { - s.WriteString(strings.Repeat(" ", runewidth.StringWidth(m.indicator))) + s.WriteString(strings.Repeat(" ", lipgloss.Width(m.indicator))) } // If there are multiple selections mark them, otherwise leave an empty space diff --git a/input/input.go b/input/input.go index fbc84c5..0ad2e54 100644 --- a/input/input.go +++ b/input/input.go @@ -11,7 +11,6 @@ import ( "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - "github.com/mattn/go-runewidth" ) type model struct { @@ -41,7 +40,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: if m.autoWidth { - m.textinput.Width = msg.Width - runewidth.StringWidth(m.textinput.Prompt) - 1 + m.textinput.Width = msg.Width - lipgloss.Width(m.textinput.Prompt) - 1 } case tea.KeyMsg: switch msg.String() { diff --git a/table/command.go b/table/command.go index d771a3b..f25b991 100644 --- a/table/command.go +++ b/table/command.go @@ -8,7 +8,7 @@ import ( "github.com/alecthomas/kong" "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" - "github.com/mattn/go-runewidth" + "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/gum/style" @@ -59,7 +59,7 @@ func (o Options) Run() error { var columns = make([]table.Column, 0, len(columnNames)) for i, title := range columnNames { - width := runewidth.StringWidth(title) + width := lipgloss.Width(title) if len(o.Widths) > i { width = o.Widths[i] } From c668e153e6244d4e7e208980dc0c5c545819031d Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Thu, 11 May 2023 23:43:52 -0400 Subject: [PATCH 09/22] feat(format): add GUM_FORMAT_THEME / GUM_FORMAT_LANGUAGE environment variable configuration --- format/options.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/format/options.go b/format/options.go index a24429c..6f36dcd 100644 --- a/format/options.go +++ b/format/options.go @@ -3,8 +3,8 @@ package format // Options is customization options for the format command. type Options struct { Template []string `arg:"" optional:"" help:"Template string to format (can also be provided via stdin)"` - Theme string `help:"Glamour theme to use for markdown formatting" default:"pink"` - Language string `help:"Programming language to parse code" short:"l" default:""` + Theme string `help:"Glamour theme to use for markdown formatting" default:"pink" env:"GUM_FORMAT_THEME"` + Language string `help:"Programming language to parse code" short:"l" default:"" env:"GUM_FORMAT_LANGUAGE"` - Type string `help:"Format to use (markdown,template,code,emoji)" enum:"markdown,template,code,emoji" short:"t" default:"markdown"` + Type string `help:"Format to use (markdown,template,code,emoji)" enum:"markdown,template,code,emoji" short:"t" default:"markdown" env:"GUM_FORMAT_TYPE"` } From 23c56854d3c03851ce549071f580e679c63a263c Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Fri, 12 May 2023 14:10:10 -0400 Subject: [PATCH 10/22] fix(ci): remove soft-serve workflow --- .github/workflows/soft-serve.yml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .github/workflows/soft-serve.yml diff --git a/.github/workflows/soft-serve.yml b/.github/workflows/soft-serve.yml deleted file mode 100644 index b10a5c9..0000000 --- a/.github/workflows/soft-serve.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: soft-serve - -on: - push: - branches: - - main - -jobs: - soft-serve: - uses: charmbracelet/meta/.github/workflows/soft-serve.yml@main - secrets: - ssh-key: "${{ secrets.CHARM_SOFT_SERVE_KEY }}" \ No newline at end of file From c8710071adf3a9f9c4931adfdc6a5706d627799c Mon Sep 17 00:00:00 2001 From: Mikael Fangel <34864484+MikaelFangel@users.noreply.github.com> Date: Mon, 15 May 2023 05:19:07 +0200 Subject: [PATCH 11/22] feature(pager): add search functionality (#321) * Added initial search functionality * Added a handler for the key presses * Added a searchbar at the bottom of the screen * Made search results cycleable by pressing n * correct start pos and ignore keys while searching * fix out of bound error when pressing n * made the matching pattern relative to the current pos * added p for searching for previous match * added highlighting to search matches * dynamically replaced all matches * fixed string highlight issue * fixed truncation issue * small simplifaction in ypos logic * made prev and next behave the same atBottom * simplified logic and fixed linter errors * updated help text * style changes * added comments * fixed truncation issue * fixes infinte loop on very long lines * added simple lipgloss truncate function * updated colors for better contrast * lint fix * initial commit for soft-wrap functionality * linter corrections and added for pager with new model * added generic functions to a utility package * fix soft lint errors * made N match previous as well as p * replaced help text when search is active * ran gofmt -w * reimplemented search and next to enabled support for dynamic highlights * made the highlight move as you progress through the search * simplified highlighter * improvements to the clean up of the highlight function * semi working reverse search * reverse search without highlight * added semi working highlight for reverser search * working version of previous match * fixed issue with single letter matches in next * added support for softwrapping * respond to soft lint warnings * removed unused function * lint * simplified matchers and fixed duplicate highlights * optimisations and change in matching pattern * fixed bug in lipglosspadding and allowed matching 1 etc. * make highlight respect user settings * fixed logic error in slice * made prev match wrap around * fix: show next/prev match help when active * updated how view port line is set * avoid crashes when regex doesn't compile * fix: spelling previous --------- Co-authored-by: Maas Lalani --- internal/utils/utils.go | 23 ++++++ pager/command.go | 15 ++-- pager/options.go | 2 + pager/pager.go | 153 +++++++++++++++++++++++++------------ pager/search.go | 163 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 300 insertions(+), 56 deletions(-) create mode 100644 internal/utils/utils.go create mode 100644 pager/search.go diff --git a/internal/utils/utils.go b/internal/utils/utils.go new file mode 100644 index 0000000..eda9240 --- /dev/null +++ b/internal/utils/utils.go @@ -0,0 +1,23 @@ +package utils + +import ( + "strings" + + "github.com/charmbracelet/lipgloss" +) + +// LipglossTruncate truncates a given line based on its lipgloss width. +func LipglossTruncate(s string, width int) string { + var i int + for i = 0; i < len(s) && lipgloss.Width(s[:i]) < width; i++ { + } //revive:disable-line:empty-block + return s[:i] +} + +// LipglossLengthPadding calculated calculates how much padding a string is given by a style. +func LipglossPadding(style lipgloss.Style) (int, int) { + render := style.Render(" ") + before := strings.Index(render, " ") + after := len(render) - len(" ") - before + return before, after +} diff --git a/pager/command.go b/pager/command.go index 47f6182..b64a41e 100644 --- a/pager/command.go +++ b/pager/command.go @@ -32,12 +32,15 @@ func (o Options) Run() error { } model := model{ - viewport: vp, - helpStyle: o.HelpStyle.ToLipgloss(), - content: o.Content, - showLineNumbers: o.ShowLineNumbers, - lineNumberStyle: o.LineNumberStyle.ToLipgloss(), - softWrap: o.SoftWrap, + viewport: vp, + helpStyle: o.HelpStyle.ToLipgloss(), + content: o.Content, + origContent: o.Content, + showLineNumbers: o.ShowLineNumbers, + lineNumberStyle: o.LineNumberStyle.ToLipgloss(), + softWrap: o.SoftWrap, + matchStyle: o.MatchStyle.ToLipgloss(), + matchHighlightStyle: o.MatchHighlightStyle.ToLipgloss(), } _, err := tea.NewProgram(model, tea.WithAltScreen()).Run() if err != nil { diff --git a/pager/options.go b/pager/options.go index 210cadc..0ce875f 100644 --- a/pager/options.go +++ b/pager/options.go @@ -11,4 +11,6 @@ type Options struct { ShowLineNumbers bool `help:"Show line numbers" default:"true"` LineNumberStyle style.Styles `embed:"" prefix:"line-number." help:"Style the line numbers" set:"defaultForeground=237" envprefix:"GUM_PAGER_LINE_NUMBER_"` SoftWrap bool `help:"Soft wrap lines" default:"false"` + MatchStyle style.Styles `embed:"" prefix:"match." help:"Style the matched text" set:"defaultForeground=212" set:"defaultBold=true" envprefix:"GUM_PAGER_MATCH_"` //nolint:staticcheck + MatchHighlightStyle style.Styles `embed:"" prefix:"match-highlight." help:"Style the matched highlight text" set:"defaultForeground=235" set:"defaultBackground=225" set:"defaultBold=true" envprefix:"GUM_PAGER_MATCH_HIGH_"` //nolint:staticcheck } diff --git a/pager/pager.go b/pager/pager.go index 685de4f..e3371da 100644 --- a/pager/pager.go +++ b/pager/pager.go @@ -9,17 +9,22 @@ import ( "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/internal/utils" "github.com/charmbracelet/lipgloss" - "github.com/mattn/go-runewidth" ) type model struct { - content string - viewport viewport.Model - helpStyle lipgloss.Style - showLineNumbers bool - lineNumberStyle lipgloss.Style - softWrap bool + content string + origContent string + viewport viewport.Model + helpStyle lipgloss.Style + showLineNumbers bool + lineNumberStyle lipgloss.Style + softWrap bool + search search + matchStyle lipgloss.Style + matchHighlightStyle lipgloss.Style + maxWidth int } func (m model) Init() tea.Cmd { @@ -29,60 +34,108 @@ func (m model) Init() tea.Cmd { func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: - m.viewport.Height = msg.Height - lipgloss.Height(m.helpStyle.Render("?")) - 1 - m.viewport.Width = msg.Width - textStyle := lipgloss.NewStyle().Width(m.viewport.Width) - var text strings.Builder - - // Determine max width of a line - maxLineWidth := m.viewport.Width - if m.softWrap { - vpStyle := m.viewport.Style - maxLineWidth -= vpStyle.GetHorizontalBorderSize() + vpStyle.GetHorizontalMargins() + vpStyle.GetHorizontalPadding() - if m.showLineNumbers { - maxLineWidth -= len(" │ ") - } - } - - for i, line := range strings.Split(m.content, "\n") { - line = strings.ReplaceAll(line, "\t", " ") - if m.showLineNumbers { - text.WriteString(m.lineNumberStyle.Render(fmt.Sprintf("%4d │ ", i+1))) - } - for m.softWrap && len(line) > maxLineWidth { - truncatedLine := runewidth.Truncate(line, maxLineWidth, "") - text.WriteString(textStyle.Render(truncatedLine)) - text.WriteString("\n") - if m.showLineNumbers { - text.WriteString(m.lineNumberStyle.Render(" │ ")) - } - line = strings.Replace(line, truncatedLine, "", 1) - } - text.WriteString(textStyle.Render(runewidth.Truncate(line, maxLineWidth, ""))) - text.WriteString("\n") - } - - diffHeight := m.viewport.Height - lipgloss.Height(text.String()) - if diffHeight > 0 && m.showLineNumbers { - remainingLines := " ~ │ " + strings.Repeat("\n ~ │ ", diffHeight-1) - text.WriteString(m.lineNumberStyle.Render(remainingLines)) - } - m.viewport.SetContent(text.String()) + m.ProcessText(msg) case tea.KeyMsg: - switch msg.String() { + return m.KeyHandler(msg) + } + + return m, nil +} + +func (m *model) ProcessText(msg tea.WindowSizeMsg) { + m.viewport.Height = msg.Height - lipgloss.Height(m.helpStyle.Render("?")) - 1 + m.viewport.Width = msg.Width + textStyle := lipgloss.NewStyle().Width(m.viewport.Width) + var text strings.Builder + + // Determine max width of a line. + m.maxWidth = m.viewport.Width + if m.softWrap { + vpStyle := m.viewport.Style + m.maxWidth -= vpStyle.GetHorizontalBorderSize() + vpStyle.GetHorizontalMargins() + vpStyle.GetHorizontalPadding() + if m.showLineNumbers { + m.maxWidth -= lipgloss.Width(" │ ") + } + } + + for i, line := range strings.Split(m.content, "\n") { + line = strings.ReplaceAll(line, "\t", " ") + if m.showLineNumbers { + text.WriteString(m.lineNumberStyle.Render(fmt.Sprintf("%4d │ ", i+1))) + } + for m.softWrap && lipgloss.Width(line) > m.maxWidth { + truncatedLine := utils.LipglossTruncate(line, m.maxWidth) + text.WriteString(textStyle.Render(truncatedLine)) + text.WriteString("\n") + if m.showLineNumbers { + text.WriteString(m.lineNumberStyle.Render(" │ ")) + } + line = strings.Replace(line, truncatedLine, "", 1) + } + text.WriteString(textStyle.Render(utils.LipglossTruncate(line, m.maxWidth))) + text.WriteString("\n") + } + + diffHeight := m.viewport.Height - lipgloss.Height(text.String()) + if diffHeight > 0 && m.showLineNumbers { + remainingLines := " ~ │ " + strings.Repeat("\n ~ │ ", diffHeight-1) + text.WriteString(m.lineNumberStyle.Render(remainingLines)) + } + m.viewport.SetContent(text.String()) +} + +func (m model) KeyHandler(key tea.KeyMsg) (model, func() tea.Msg) { + var cmd tea.Cmd + if m.search.active { + switch key.String() { + case "enter": + if m.search.input.Value() != "" { + m.content = m.origContent + m.search.Execute(&m) + + // Trigger a view update to highlight the found matches. + m.search.NextMatch(&m) + m.ProcessText(tea.WindowSizeMsg{Height: m.viewport.Height + 2, Width: m.viewport.Width}) + } else { + m.search.Done() + } + case "ctrl+d", "ctrl+c", "esc": + m.search.Done() + default: + m.search.input, cmd = m.search.input.Update(key) + } + } else { + switch key.String() { case "g": m.viewport.GotoTop() case "G": m.viewport.GotoBottom() + case "/": + m.search.Begin() + case "p", "N": + m.search.PrevMatch(&m) + m.ProcessText(tea.WindowSizeMsg{Height: m.viewport.Height + 2, Width: m.viewport.Width}) + case "n": + m.search.NextMatch(&m) + m.ProcessText(tea.WindowSizeMsg{Height: m.viewport.Height + 2, Width: m.viewport.Width}) case "q", "ctrl+c", "esc": return m, tea.Quit } + m.viewport, cmd = m.viewport.Update(key) } - var cmd tea.Cmd - m.viewport, cmd = m.viewport.Update(msg) + return m, cmd } func (m model) View() string { - return m.viewport.View() + m.helpStyle.Render("\n ↑/↓: Navigate • q: Quit") + helpMsg := "\n ↑/↓: Navigate • q: Quit • /: Search " + if m.search.query != nil { + helpMsg += "• n: Next Match " + helpMsg += "• N: Prev Match " + } + if m.search.active { + return m.viewport.View() + "\n " + m.search.input.View() + } + + return m.viewport.View() + m.helpStyle.Render(helpMsg) } diff --git a/pager/search.go b/pager/search.go new file mode 100644 index 0000000..a15004b --- /dev/null +++ b/pager/search.go @@ -0,0 +1,163 @@ +package pager + +import ( + "fmt" + "regexp" + "strings" + + "github.com/charmbracelet/bubbles/textinput" + "github.com/charmbracelet/gum/internal/utils" + "github.com/charmbracelet/lipgloss" +) + +type search struct { + active bool + input textinput.Model + query *regexp.Regexp + matchIndex int + matchLipglossStr string + matchString string +} + +func (s *search) new() { + input := textinput.New() + input.Placeholder = "search" + input.Prompt = "/" + input.PromptStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("240")) + s.input = input +} + +func (s *search) Begin() { + s.new() + s.active = true + s.input.Focus() +} + +// Execute find all lines in the model with a match. +func (s *search) Execute(m *model) { + defer s.Done() + if s.input.Value() == "" { + s.query = nil + return + } + + var err error + s.query, err = regexp.Compile(s.input.Value()) + if err != nil { + s.query = nil + return + } + query := regexp.MustCompile(fmt.Sprintf("(%s)", s.query.String())) + m.content = query.ReplaceAllString(m.content, m.matchStyle.Render("$1")) + + // Recompile the regex to match the an replace the highlights. + leftPad, _ := utils.LipglossPadding(m.matchStyle) + matchingString := regexp.QuoteMeta(m.matchStyle.Render()[:leftPad]) + s.query.String() + regexp.QuoteMeta(m.matchStyle.Render()[leftPad:]) + s.query, err = regexp.Compile(matchingString) + if err != nil { + s.query = nil + } +} + +func (s *search) Done() { + s.active = false + + // To account for the first match is always executed. + s.matchIndex = -1 +} + +func (s *search) NextMatch(m *model) { + // Check that we are within bounds. + if s.query == nil { + return + } + + // Remove previous highlight. + m.content = strings.Replace(m.content, s.matchLipglossStr, s.matchString, 1) + + // Highlight the next match. + allMatches := s.query.FindAllStringIndex(m.content, -1) + if len(allMatches) == 0 { + return + } + + leftPad, rightPad := utils.LipglossPadding(m.matchStyle) + s.matchIndex = (s.matchIndex + 1) % len(allMatches) + match := allMatches[s.matchIndex] + lhs := m.content[:match[0]] + rhs := m.content[match[0]:] + s.matchString = m.content[match[0]:match[1]] + s.matchLipglossStr = m.matchHighlightStyle.Render(s.matchString[leftPad : len(s.matchString)-rightPad]) + m.content = lhs + strings.Replace(rhs, m.content[match[0]:match[1]], s.matchLipglossStr, 1) + + // Update the viewport position. + var line int + formatStr := softWrapEm(m.content, m.maxWidth, m.softWrap) + index := strings.Index(formatStr, s.matchLipglossStr) + if index != -1 { + line = strings.Count(formatStr[:index], "\n") + } + + // Only update if the match is not within the viewport. + if index != -1 && (line > m.viewport.YOffset-1+m.viewport.VisibleLineCount()-1 || line < m.viewport.YOffset) { + m.viewport.SetYOffset(line) + } +} + +func (s *search) PrevMatch(m *model) { + // Check that we are within bounds. + if s.query == nil { + return + } + + // Remove previous highlight. + m.content = strings.Replace(m.content, s.matchLipglossStr, s.matchString, 1) + + // Highlight the previous match. + allMatches := s.query.FindAllStringIndex(m.content, -1) + if len(allMatches) == 0 { + return + } + + s.matchIndex = (s.matchIndex - 1) % len(allMatches) + if s.matchIndex < 0 { + s.matchIndex = len(allMatches) - 1 + } + + leftPad, rightPad := utils.LipglossPadding(m.matchStyle) + match := allMatches[s.matchIndex] + lhs := m.content[:match[0]] + rhs := m.content[match[0]:] + s.matchString = m.content[match[0]:match[1]] + s.matchLipglossStr = m.matchHighlightStyle.Render(s.matchString[leftPad : len(s.matchString)-rightPad]) + m.content = lhs + strings.Replace(rhs, m.content[match[0]:match[1]], s.matchLipglossStr, 1) + + // Update the viewport position. + var line int + formatStr := softWrapEm(m.content, m.maxWidth, m.softWrap) + index := strings.Index(formatStr, s.matchLipglossStr) + if index != -1 { + line = strings.Count(formatStr[:index], "\n") + } + + // Only update if the match is not within the viewport. + if index != -1 && (line > m.viewport.YOffset-1+m.viewport.VisibleLineCount()-1 || line < m.viewport.YOffset) { + m.viewport.SetYOffset(line) + } +} + +func softWrapEm(str string, maxWidth int, softWrap bool) string { + var text strings.Builder + for _, line := range strings.Split(str, "\n") { + for softWrap && lipgloss.Width(line) > maxWidth { + truncatedLine := utils.LipglossTruncate(line, maxWidth) + text.WriteString(truncatedLine) + text.WriteString("\n") + line = strings.Replace(line, truncatedLine, "", 1) + } + text.WriteString(utils.LipglossTruncate(line, maxWidth)) + text.WriteString("\n") + } + + return text.String() +} From b23ebce896dbbc564d39aef78008997186fdb4e0 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Thu, 18 May 2023 11:34:53 -0400 Subject: [PATCH 12/22] fix: measure runes instead of bytes when truncating There are a couple of gotchas in LipGlossTruncate: * len() returns the number of bytes in a string * slicing a string slices it on a byte level The fix would normally be to convert the string to a slice of runes and operate on that new slice: r := []rune(str) However, reflow already contains an ansi-aware truncate feature that we can use instead as a drop-in replacement for the LipGlossTruncate function. --- internal/utils/utils.go | 8 -------- pager/pager.go | 6 +++--- pager/search.go | 5 +++-- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index eda9240..186988c 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -6,14 +6,6 @@ import ( "github.com/charmbracelet/lipgloss" ) -// LipglossTruncate truncates a given line based on its lipgloss width. -func LipglossTruncate(s string, width int) string { - var i int - for i = 0; i < len(s) && lipgloss.Width(s[:i]) < width; i++ { - } //revive:disable-line:empty-block - return s[:i] -} - // LipglossLengthPadding calculated calculates how much padding a string is given by a style. func LipglossPadding(style lipgloss.Style) (int, int) { render := style.Render(" ") diff --git a/pager/pager.go b/pager/pager.go index e3371da..5091ea3 100644 --- a/pager/pager.go +++ b/pager/pager.go @@ -9,8 +9,8 @@ import ( "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/gum/internal/utils" "github.com/charmbracelet/lipgloss" + "github.com/muesli/reflow/truncate" ) type model struct { @@ -64,7 +64,7 @@ func (m *model) ProcessText(msg tea.WindowSizeMsg) { text.WriteString(m.lineNumberStyle.Render(fmt.Sprintf("%4d │ ", i+1))) } for m.softWrap && lipgloss.Width(line) > m.maxWidth { - truncatedLine := utils.LipglossTruncate(line, m.maxWidth) + truncatedLine := truncate.String(line, uint(m.maxWidth)) text.WriteString(textStyle.Render(truncatedLine)) text.WriteString("\n") if m.showLineNumbers { @@ -72,7 +72,7 @@ func (m *model) ProcessText(msg tea.WindowSizeMsg) { } line = strings.Replace(line, truncatedLine, "", 1) } - text.WriteString(textStyle.Render(utils.LipglossTruncate(line, m.maxWidth))) + text.WriteString(textStyle.Render(truncate.String(line, uint(m.maxWidth)))) text.WriteString("\n") } diff --git a/pager/search.go b/pager/search.go index a15004b..b112d7d 100644 --- a/pager/search.go +++ b/pager/search.go @@ -8,6 +8,7 @@ import ( "github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/gum/internal/utils" "github.com/charmbracelet/lipgloss" + "github.com/muesli/reflow/truncate" ) type search struct { @@ -150,12 +151,12 @@ func softWrapEm(str string, maxWidth int, softWrap bool) string { var text strings.Builder for _, line := range strings.Split(str, "\n") { for softWrap && lipgloss.Width(line) > maxWidth { - truncatedLine := utils.LipglossTruncate(line, maxWidth) + truncatedLine := truncate.String(line, uint(maxWidth)) text.WriteString(truncatedLine) text.WriteString("\n") line = strings.Replace(line, truncatedLine, "", 1) } - text.WriteString(utils.LipglossTruncate(line, maxWidth)) + text.WriteString(truncate.String(line, uint(maxWidth))) text.WriteString("\n") } From 6e802805cf5bebdd2f43aacb9ba30ba9ecfb05ca Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Thu, 18 May 2023 12:20:41 -0400 Subject: [PATCH 13/22] fix(docs): correct LipglossPadding doc comment --- internal/utils/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 186988c..0e38598 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -6,7 +6,7 @@ import ( "github.com/charmbracelet/lipgloss" ) -// LipglossLengthPadding calculated calculates how much padding a string is given by a style. +// LipglossPadding calculates how much padding a string is given by a style. func LipglossPadding(style lipgloss.Style) (int, int) { render := style.Render(" ") before := strings.Index(render, " ") From 4c3cc1773f53a0039885aba3d0c7bce4b8513844 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Mon, 22 May 2023 15:00:16 -0400 Subject: [PATCH 14/22] feat: add kaomoji example --- examples/kaomoji.sh | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 examples/kaomoji.sh diff --git a/examples/kaomoji.sh b/examples/kaomoji.sh new file mode 100644 index 0000000..1684656 --- /dev/null +++ b/examples/kaomoji.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +# If the user passes '-h', '--help', or 'help' print out a little bit of help. +# text. +case "$1" in + "-h" | "--help" | "help") + printf 'Generate kaomojis on request.\n\n' + printf 'Usage: %s [kind]\n' "$(basename "$0")" + exit 1 + ;; +esac + +# The user can pass an argument like "bear" or "angry" to specify the general +# kind of Kaomoji produced. +sentiment="" +if [[ $1 != "" ]]; then + sentiment=" $1" +fi + +# Ask mods to generate Kaomojis. Save the output in a variable. +kaomoji="$(mods "generate 10${sentiment} kaomojis. number them and put each one on its own line.")" +if [[ $kaomoji == "" ]]; then + exit 1 +fi + +# Pipe mods output to gum so the user can choose the perfect kaomoji. Save that +# choice in a variable. Also note that we're using cut to drop the item number +# in front of the Kaomoji. +choice="$(echo "$kaomoji" | gum choose | cut -d ' ' -f 2)" +if [[ $choice == "" ]]; then + exit 1 +fi + +# If xsel (X11) or pbcopy (macOS) exists, copy to the clipboard. If not, just +# print the Kaomoji. +if command -v xsel &> /dev/null; then + printf '%s' "$choice" | xclip -sel clip # X11 +elif command -v pbcopy &> /dev/null; then + printf '%s' "$choice" | pbcopy # macOS +else + # We can't copy, so just print it out. + printf 'Here you go: %s\n' "$choice" + exit 0 +fi + +# We're done! +printf 'Copied %s to the clipboard\n' "$choice" From 25ff33e7106d58d2691c1fef7d8d6f8f5f95d49d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 05:07:35 +0000 Subject: [PATCH 15/22] feat(deps): bump github.com/charmbracelet/bubbletea Bumps [github.com/charmbracelet/bubbletea](https://github.com/charmbracelet/bubbletea) from 0.23.3-0.20230316100943-248eb83001a7 to 0.24.0. - [Release notes](https://github.com/charmbracelet/bubbletea/releases) - [Commits](https://github.com/charmbracelet/bubbletea/commits/v0.24.0) --- updated-dependencies: - dependency-name: github.com/charmbracelet/bubbletea dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 8c0b11e..8c8f1cb 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/alecthomas/kong v0.7.1 github.com/alecthomas/mango-kong v0.1.0 github.com/charmbracelet/bubbles v0.15.1-0.20230501135844-7590e13c2a27 - github.com/charmbracelet/bubbletea v0.23.3-0.20230316100943-248eb83001a7 + github.com/charmbracelet/bubbletea v0.24.0 github.com/charmbracelet/glamour v0.6.0 github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707 github.com/mattn/go-isatty v0.0.18 diff --git a/go.sum b/go.sum index 9fab4ad..e28846d 100644 --- a/go.sum +++ b/go.sum @@ -13,13 +13,11 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/charmbracelet/bubbles v0.15.1-0.20230324185713-1de5816ab4f7 h1:16QEZgcSr80fcXZBlqSZG5F+1j5CATd/ZLcNjV8DBdU= -github.com/charmbracelet/bubbles v0.15.1-0.20230324185713-1de5816ab4f7/go.mod h1:39HL8bnL0foloiENA/KvD+3mNg5SqWQV2Qh3eY/4ey4= github.com/charmbracelet/bubbles v0.15.1-0.20230501135844-7590e13c2a27 h1:IF1XCxwu1M1J+n+akXYUm4CQh1B+2QdZxhJEW4G0kG0= github.com/charmbracelet/bubbles v0.15.1-0.20230501135844-7590e13c2a27/go.mod h1:39HL8bnL0foloiENA/KvD+3mNg5SqWQV2Qh3eY/4ey4= github.com/charmbracelet/bubbletea v0.23.1/go.mod h1:JAfGK/3/pPKHTnAS8JIE2u9f61BjWTQY57RbT25aMXU= -github.com/charmbracelet/bubbletea v0.23.3-0.20230316100943-248eb83001a7 h1:QWRijV4kfijpili/tRA9FAxS1Pw1B2n4+RF2UVOmBbw= -github.com/charmbracelet/bubbletea v0.23.3-0.20230316100943-248eb83001a7/go.mod h1:/9VgEZjOAyBTwlaj5ILlkrpeuulz+b2ITKJNKo/5vK0= +github.com/charmbracelet/bubbletea v0.24.0 h1:l8PHrft/GIeikDPCUhQe53AJrDD8xGSn0Agirh8xbe8= +github.com/charmbracelet/bubbletea v0.24.0/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg= github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= From accce59ed18ef4e9e0ebda3b06616298109fbb09 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Wed, 24 May 2023 12:49:19 -0400 Subject: [PATCH 16/22] fix: bump to v0.24.1 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 8c8f1cb..97d52cc 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/alecthomas/kong v0.7.1 github.com/alecthomas/mango-kong v0.1.0 github.com/charmbracelet/bubbles v0.15.1-0.20230501135844-7590e13c2a27 - github.com/charmbracelet/bubbletea v0.24.0 + github.com/charmbracelet/bubbletea v0.24.1 github.com/charmbracelet/glamour v0.6.0 github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707 github.com/mattn/go-isatty v0.0.18 diff --git a/go.sum b/go.sum index e28846d..34461df 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ github.com/charmbracelet/bubbles v0.15.1-0.20230501135844-7590e13c2a27/go.mod h1 github.com/charmbracelet/bubbletea v0.23.1/go.mod h1:JAfGK/3/pPKHTnAS8JIE2u9f61BjWTQY57RbT25aMXU= github.com/charmbracelet/bubbletea v0.24.0 h1:l8PHrft/GIeikDPCUhQe53AJrDD8xGSn0Agirh8xbe8= github.com/charmbracelet/bubbletea v0.24.0/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg= +github.com/charmbracelet/bubbletea v0.24.1 h1:LpdYfnu+Qc6XtvMz6d/6rRY71yttHTP5HtrjMgWvixc= +github.com/charmbracelet/bubbletea v0.24.1/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg= github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= From a892c39289d031f01db77dde85435e53d49ae323 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 30 May 2023 14:29:41 +0000 Subject: [PATCH 17/22] fix: format pager/options.go Signed-off-by: Carlos Alexandro Becker --- pager/options.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pager/options.go b/pager/options.go index 0ce875f..53b6c7c 100644 --- a/pager/options.go +++ b/pager/options.go @@ -5,12 +5,12 @@ import "github.com/charmbracelet/gum/style" // Options are the options for the pager. type Options struct { //nolint:staticcheck - Style style.Styles `embed:"" help:"Style the pager" set:"defaultBorder=rounded" set:"defaultPadding=0 1" set:"defaultBorderForeground=212" envprefix:"GUM_PAGER_"` - HelpStyle style.Styles `embed:"" prefix:"help." help:"Style the help text" set:"defaultForeground=241" envprefix:"GUM_PAGER_HELP_"` - Content string `arg:"" optional:"" help:"Display content to scroll"` - ShowLineNumbers bool `help:"Show line numbers" default:"true"` - LineNumberStyle style.Styles `embed:"" prefix:"line-number." help:"Style the line numbers" set:"defaultForeground=237" envprefix:"GUM_PAGER_LINE_NUMBER_"` - SoftWrap bool `help:"Soft wrap lines" default:"false"` - MatchStyle style.Styles `embed:"" prefix:"match." help:"Style the matched text" set:"defaultForeground=212" set:"defaultBold=true" envprefix:"GUM_PAGER_MATCH_"` //nolint:staticcheck - MatchHighlightStyle style.Styles `embed:"" prefix:"match-highlight." help:"Style the matched highlight text" set:"defaultForeground=235" set:"defaultBackground=225" set:"defaultBold=true" envprefix:"GUM_PAGER_MATCH_HIGH_"` //nolint:staticcheck + Style style.Styles `embed:"" help:"Style the pager" set:"defaultBorder=rounded" set:"defaultPadding=0 1" set:"defaultBorderForeground=212" envprefix:"GUM_PAGER_"` + HelpStyle style.Styles `embed:"" prefix:"help." help:"Style the help text" set:"defaultForeground=241" envprefix:"GUM_PAGER_HELP_"` + Content string `arg:"" optional:"" help:"Display content to scroll"` + ShowLineNumbers bool `help:"Show line numbers" default:"true"` + LineNumberStyle style.Styles `embed:"" prefix:"line-number." help:"Style the line numbers" set:"defaultForeground=237" envprefix:"GUM_PAGER_LINE_NUMBER_"` + SoftWrap bool `help:"Soft wrap lines" default:"false"` + MatchStyle style.Styles `embed:"" prefix:"match." help:"Style the matched text" set:"defaultForeground=212" set:"defaultBold=true" envprefix:"GUM_PAGER_MATCH_"` //nolint:staticcheck + MatchHighlightStyle style.Styles `embed:"" prefix:"match-highlight." help:"Style the matched highlight text" set:"defaultForeground=235" set:"defaultBackground=225" set:"defaultBold=true" envprefix:"GUM_PAGER_MATCH_HIGH_"` //nolint:staticcheck } From 5a4b12c8ca9c0f97c3ef99ff946ac64bc47f183f Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 30 May 2023 14:19:53 +0000 Subject: [PATCH 18/22] feat: gum filter --no-sort Signed-off-by: Carlos Alexandro Becker --- filter/command.go | 1 + filter/filter.go | 7 ++++++- filter/options.go | 1 + go.mod | 8 ++++---- go.sum | 24 ++++-------------------- 5 files changed, 16 insertions(+), 25 deletions(-) diff --git a/filter/command.go b/filter/command.go index c4581c6..af62920 100644 --- a/filter/command.go +++ b/filter/command.go @@ -89,6 +89,7 @@ func (o Options) Run() error { limit: o.Limit, reverse: o.Reverse, fuzzy: o.Fuzzy, + sort: o.Sort, }, options...) tm, err := p.Run() diff --git a/filter/filter.go b/filter/filter.go index 54df59e..69d62f5 100644 --- a/filter/filter.go +++ b/filter/filter.go @@ -44,6 +44,7 @@ type model struct { unselectedPrefixStyle lipgloss.Style reverse bool fuzzy bool + sort bool } func (m model) Init() tea.Cmd { return nil } @@ -200,7 +201,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // A character was entered, this likely means that the text input has // changed. This suggests that the matches are outdated, so update them. if m.fuzzy { - m.matches = fuzzy.Find(m.textinput.Value(), m.choices) + if m.sort { + m.matches = fuzzy.Find(m.textinput.Value(), m.choices) + } else { + m.matches = fuzzy.FindNoSort(m.textinput.Value(), m.choices) + } } else { m.matches = exactMatches(m.textinput.Value(), m.choices) } diff --git a/filter/options.go b/filter/options.go index 32f72eb..1392d91 100644 --- a/filter/options.go +++ b/filter/options.go @@ -25,4 +25,5 @@ type Options struct { Value string `help:"Initial filter value" default:"" env:"GUM_FILTER_VALUE"` Reverse bool `help:"Display from the bottom of the screen" env:"GUM_FILTER_REVERSE"` Fuzzy bool `help:"Enable fuzzy matching" default:"true" env:"GUM_FILTER_FUZZY" negatable:""` + Sort bool `help:"Sort the results" default:"true" env:"GUM_FILTER_SORT" negatable:""` } diff --git a/go.mod b/go.mod index 97d52cc..0f4daf6 100644 --- a/go.mod +++ b/go.mod @@ -5,15 +5,15 @@ go 1.18 require ( github.com/alecthomas/kong v0.7.1 github.com/alecthomas/mango-kong v0.1.0 - github.com/charmbracelet/bubbles v0.15.1-0.20230501135844-7590e13c2a27 + github.com/charmbracelet/bubbles v0.15.1-0.20230525133559-6034e6818456 github.com/charmbracelet/bubbletea v0.24.1 github.com/charmbracelet/glamour v0.6.0 github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707 github.com/mattn/go-isatty v0.0.18 - github.com/mattn/go-runewidth v0.0.14 + github.com/muesli/reflow v0.3.0 github.com/muesli/roff v0.1.0 github.com/muesli/termenv v0.15.2-0.20230323153104-73a40463ff25 - github.com/sahilm/fuzzy v0.1.0 + github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f ) require ( @@ -27,11 +27,11 @@ require ( github.com/gorilla/css v1.0.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-localereader v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect github.com/microcosm-cc/bluemonday v1.0.23 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/mango v0.2.0 // indirect - github.com/muesli/reflow v0.3.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/yuin/goldmark v1.5.4 // indirect diff --git a/go.sum b/go.sum index 34461df..cc7a842 100644 --- a/go.sum +++ b/go.sum @@ -13,20 +13,14 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/charmbracelet/bubbles v0.15.1-0.20230501135844-7590e13c2a27 h1:IF1XCxwu1M1J+n+akXYUm4CQh1B+2QdZxhJEW4G0kG0= -github.com/charmbracelet/bubbles v0.15.1-0.20230501135844-7590e13c2a27/go.mod h1:39HL8bnL0foloiENA/KvD+3mNg5SqWQV2Qh3eY/4ey4= -github.com/charmbracelet/bubbletea v0.23.1/go.mod h1:JAfGK/3/pPKHTnAS8JIE2u9f61BjWTQY57RbT25aMXU= -github.com/charmbracelet/bubbletea v0.24.0 h1:l8PHrft/GIeikDPCUhQe53AJrDD8xGSn0Agirh8xbe8= -github.com/charmbracelet/bubbletea v0.24.0/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg= +github.com/charmbracelet/bubbles v0.15.1-0.20230525133559-6034e6818456 h1:BzIuNg6fFywxp6qI96LH/08uL2Hi9dsqTOqSsRTL6BI= +github.com/charmbracelet/bubbles v0.15.1-0.20230525133559-6034e6818456/go.mod h1:D4UDwNOTGBU2NtVEWtwfhStJO75L8OsqcO7csWH6RrA= github.com/charmbracelet/bubbletea v0.24.1 h1:LpdYfnu+Qc6XtvMz6d/6rRY71yttHTP5HtrjMgWvixc= github.com/charmbracelet/bubbletea v0.24.1/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg= github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc= -github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= -github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk= github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707 h1:dXv2HjaDlJZj7wLpTjg1P4B68bdvoXfx7+VXF2/RelY= github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707/go.mod h1:BDceYFEeE5FBoGZeuApZ+V4wSgi8AOIHoryyjYbCTHM= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -41,37 +35,30 @@ github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -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/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY= github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4= -github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/mango v0.2.0 h1:iNNc0c5VLQ6fsMgAqGQofByNUBH2Q2nEbD6TaI+5yyQ= github.com/muesli/mango v0.2.0/go.mod h1:5XFpbC8jY5UUv89YQciiXNlbi+iJgt29VDC5xbzrLL4= -github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/roff v0.1.0 h1:YD0lalCotmYuF5HhZliKWlIx7IEhiXeSfq7hNjFqGF8= github.com/muesli/roff v0.1.0/go.mod h1:pjAHQM9hdUUwm/krAfrLGgJkXJ+YuhtsfZ42kieB2Ig= -github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= github.com/muesli/termenv v0.13.0/go.mod h1:sP1+uffeLaEYpyOTb8pLCUctGcGLnoFjSn4YJK5e2bc= github.com/muesli/termenv v0.15.2-0.20230323153104-73a40463ff25 h1:bgCNxFKF+mM5GxpNvkGleUFt12xOzLOzmMOytttpeK4= github.com/muesli/termenv v0.15.2-0.20230323153104-73a40463ff25/go.mod h1:puu7Fg2fBjAuOzC9hb6zDO/s86uLSYrBlPkIplp2EiA= @@ -83,8 +70,8 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= -github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y= +github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -99,10 +86,7 @@ golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= From 3f7db714fff24228dca5977d2d8806eeba772207 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Wed, 31 May 2023 11:09:15 -0400 Subject: [PATCH 19/22] fix(format): indentation issues --- go.mod | 3 ++- go.sum | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 0f4daf6..9e464f6 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/alecthomas/mango-kong v0.1.0 github.com/charmbracelet/bubbles v0.15.1-0.20230525133559-6034e6818456 github.com/charmbracelet/bubbletea v0.24.1 - github.com/charmbracelet/glamour v0.6.0 + github.com/charmbracelet/glamour v0.6.1-0.20230531150759-6d5b52861a9d github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707 github.com/mattn/go-isatty v0.0.18 github.com/muesli/reflow v0.3.0 @@ -18,6 +18,7 @@ require ( require ( github.com/alecthomas/chroma v0.10.0 // indirect + github.com/alecthomas/chroma/v2 v2.7.0 // indirect github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect diff --git a/go.sum b/go.sum index cc7a842..0c7cf71 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0= github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s= +github.com/alecthomas/chroma/v2 v2.7.0 h1:hm1rY6c/Ob4eGclpQ7X/A3yhqBOZNUTk9q+yhyLIViI= +github.com/alecthomas/chroma/v2 v2.7.0/go.mod h1:yrkMI9807G1ROx13fhe1v6PN2DDeaR73L3d+1nmYQtw= github.com/alecthomas/kong v0.7.1 h1:azoTh0IOfwlAX3qN9sHWTxACE2oV8Bg2gAwBsMwDQY4= github.com/alecthomas/kong v0.7.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U= github.com/alecthomas/mango-kong v0.1.0 h1:iFVfP1k1K4qpml3JUQmD5I8MCQYfIvsD9mRdrw7jJC4= @@ -19,6 +21,10 @@ github.com/charmbracelet/bubbletea v0.24.1 h1:LpdYfnu+Qc6XtvMz6d/6rRY71yttHTP5Ht github.com/charmbracelet/bubbletea v0.24.1/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg= github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc= +github.com/charmbracelet/glamour v0.6.1-0.20230531150050-63cd3b88ae05 h1:+68qHQWQIn8WsZ0NiKpYlxLPkAEYgq8RkgahsJz3Wqg= +github.com/charmbracelet/glamour v0.6.1-0.20230531150050-63cd3b88ae05/go.mod h1:swCB3CXFsh22H1ESDYdY1tirLiNqCziulDyJ1B6Nt7Q= +github.com/charmbracelet/glamour v0.6.1-0.20230531150759-6d5b52861a9d h1:S4Ejl/M2VrryIgDrDbiuvkwMUDa67/t/H3Wz3i2/vUw= +github.com/charmbracelet/glamour v0.6.1-0.20230531150759-6d5b52861a9d/go.mod h1:swCB3CXFsh22H1ESDYdY1tirLiNqCziulDyJ1B6Nt7Q= github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707 h1:dXv2HjaDlJZj7wLpTjg1P4B68bdvoXfx7+VXF2/RelY= github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707/go.mod h1:BDceYFEeE5FBoGZeuApZ+V4wSgi8AOIHoryyjYbCTHM= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= From 3609fe1da8b6d3937dcf85b15e62becb1d9c087e Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Wed, 31 May 2023 14:07:00 -0400 Subject: [PATCH 20/22] feat: use file picker v0.16.1 --- file/command.go | 2 +- go.mod | 2 +- go.sum | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/file/command.go b/file/command.go index 71c1b79..e7daa14 100644 --- a/file/command.go +++ b/file/command.go @@ -37,7 +37,7 @@ func (o Options) Run() error { fp.DirAllowed = o.Directory fp.FileAllowed = o.File fp.ShowHidden = o.All - fp.Styles = filepicker.DefaultStyles + fp.Styles = filepicker.DefaultStyles() fp.Styles.Cursor = o.CursorStyle.ToLipgloss() fp.Styles.Symlink = o.SymlinkStyle.ToLipgloss() fp.Styles.Directory = o.DirectoryStyle.ToLipgloss() diff --git a/go.mod b/go.mod index 9e464f6..c81f0bd 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/alecthomas/kong v0.7.1 github.com/alecthomas/mango-kong v0.1.0 - github.com/charmbracelet/bubbles v0.15.1-0.20230525133559-6034e6818456 + github.com/charmbracelet/bubbles v0.16.1 github.com/charmbracelet/bubbletea v0.24.1 github.com/charmbracelet/glamour v0.6.1-0.20230531150759-6d5b52861a9d github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707 diff --git a/go.sum b/go.sum index 0c7cf71..19091a9 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,8 @@ github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuP github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/charmbracelet/bubbles v0.15.1-0.20230525133559-6034e6818456 h1:BzIuNg6fFywxp6qI96LH/08uL2Hi9dsqTOqSsRTL6BI= github.com/charmbracelet/bubbles v0.15.1-0.20230525133559-6034e6818456/go.mod h1:D4UDwNOTGBU2NtVEWtwfhStJO75L8OsqcO7csWH6RrA= +github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= +github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= github.com/charmbracelet/bubbletea v0.24.1 h1:LpdYfnu+Qc6XtvMz6d/6rRY71yttHTP5HtrjMgWvixc= github.com/charmbracelet/bubbletea v0.24.1/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg= github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= From 8f17aa3f9a468d2ad0c84d683005994239fb40e3 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Mon, 5 Jun 2023 16:05:22 -0400 Subject: [PATCH 21/22] feat(write,input): add `--cursor.mode=hide,blink,static` --- cursor/cursor.go | 12 ++++++++++++ input/command.go | 2 ++ input/options.go | 1 + write/command.go | 2 ++ write/options.go | 1 + 5 files changed, 18 insertions(+) create mode 100644 cursor/cursor.go diff --git a/cursor/cursor.go b/cursor/cursor.go new file mode 100644 index 0000000..aa49c05 --- /dev/null +++ b/cursor/cursor.go @@ -0,0 +1,12 @@ +package cursor + +import ( + "github.com/charmbracelet/bubbles/cursor" +) + +// Modes maps strings to cursor modes. +var Modes = map[string]cursor.Mode{ + "blink": cursor.CursorBlink, + "hide": cursor.CursorHide, + "static": cursor.CursorStatic, +} diff --git a/input/command.go b/input/command.go index c15e180..4d3edb2 100644 --- a/input/command.go +++ b/input/command.go @@ -8,6 +8,7 @@ import ( "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/cursor" "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/gum/style" @@ -29,6 +30,7 @@ func (o Options) Run() error { i.Width = o.Width i.PromptStyle = o.PromptStyle.ToLipgloss() i.Cursor.Style = o.CursorStyle.ToLipgloss() + i.Cursor.SetMode(cursor.Modes[o.CursorMode]) i.CharLimit = o.CharLimit if o.Password { diff --git a/input/options.go b/input/options.go index 86eef6a..77cc683 100644 --- a/input/options.go +++ b/input/options.go @@ -8,6 +8,7 @@ type Options struct { Prompt string `help:"Prompt to display" default:"> " env:"GUM_INPUT_PROMPT"` PromptStyle style.Styles `embed:"" prefix:"prompt." envprefix:"GUM_INPUT_PROMPT_"` CursorStyle style.Styles `embed:"" prefix:"cursor." set:"defaultForeground=212" envprefix:"GUM_INPUT_CURSOR_"` + CursorMode string `prefix:"cursor." name:"mode" help:"Cursor mode" default:"blink" enum:"blink,hide,static" env:"GUM_INPUT_CURSOR_MODE"` Value string `help:"Initial value (can also be passed via stdin)" default:""` CharLimit int `help:"Maximum value length (0 for no limit)" default:"400"` Width int `help:"Input width (0 for terminal width)" default:"40" env:"GUM_INPUT_WIDTH"` diff --git a/write/command.go b/write/command.go index 84fcd76..76e46b2 100644 --- a/write/command.go +++ b/write/command.go @@ -9,6 +9,7 @@ import ( "github.com/charmbracelet/bubbles/textarea" tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/gum/cursor" "github.com/charmbracelet/gum/internal/exit" "github.com/charmbracelet/gum/internal/stdin" "github.com/charmbracelet/gum/style" @@ -43,6 +44,7 @@ func (o Options) Run() error { a.BlurredStyle = style a.FocusedStyle = style a.Cursor.Style = o.CursorStyle.ToLipgloss() + a.Cursor.SetMode(cursor.Modes[o.CursorMode]) a.SetWidth(o.Width) a.SetHeight(o.Height) diff --git a/write/options.go b/write/options.go index cfae3c9..af5b422 100644 --- a/write/options.go +++ b/write/options.go @@ -13,6 +13,7 @@ type Options struct { ShowLineNumbers bool `help:"Show line numbers" default:"false" env:"GUM_WRITE_SHOW_LINE_NUMBERS"` Value string `help:"Initial value (can be passed via stdin)" default:"" env:"GUM_WRITE_VALUE"` CharLimit int `help:"Maximum value length (0 for no limit)" default:"400"` + CursorMode string `prefix:"cursor." name:"mode" help:"Cursor mode" default:"blink" enum:"blink,hide,static" env:"GUM_WRITE_CURSOR_MODE"` BaseStyle style.Styles `embed:"" prefix:"base." envprefix:"GUM_WRITE_BASE_"` CursorLineNumberStyle style.Styles `embed:"" prefix:"cursor-line-number." set:"defaultForeground=7" envprefix:"GUM_WRITE_CURSOR_LINE_NUMBER_"` From 0010018d61fcaf6316c022e2d775d3d10d7ee60f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jun 2023 05:14:14 +0000 Subject: [PATCH 22/22] feat(deps): bump github.com/charmbracelet/bubbletea Bumps [github.com/charmbracelet/bubbletea](https://github.com/charmbracelet/bubbletea) from 0.24.1 to 0.24.2. - [Release notes](https://github.com/charmbracelet/bubbletea/releases) - [Commits](https://github.com/charmbracelet/bubbletea/compare/v0.24.1...v0.24.2) --- updated-dependencies: - dependency-name: github.com/charmbracelet/bubbletea dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 3 +-- go.sum | 40 ++++------------------------------------ 2 files changed, 5 insertions(+), 38 deletions(-) diff --git a/go.mod b/go.mod index c81f0bd..492f496 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/alecthomas/kong v0.7.1 github.com/alecthomas/mango-kong v0.1.0 github.com/charmbracelet/bubbles v0.16.1 - github.com/charmbracelet/bubbletea v0.24.1 + github.com/charmbracelet/bubbletea v0.24.2 github.com/charmbracelet/glamour v0.6.1-0.20230531150759-6d5b52861a9d github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707 github.com/mattn/go-isatty v0.0.18 @@ -17,7 +17,6 @@ require ( ) require ( - github.com/alecthomas/chroma v0.10.0 // indirect github.com/alecthomas/chroma/v2 v2.7.0 // indirect github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect diff --git a/go.sum b/go.sum index 19091a9..0345603 100644 --- a/go.sum +++ b/go.sum @@ -1,40 +1,27 @@ -github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0= -github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek= -github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s= +github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink= github.com/alecthomas/chroma/v2 v2.7.0 h1:hm1rY6c/Ob4eGclpQ7X/A3yhqBOZNUTk9q+yhyLIViI= github.com/alecthomas/chroma/v2 v2.7.0/go.mod h1:yrkMI9807G1ROx13fhe1v6PN2DDeaR73L3d+1nmYQtw= github.com/alecthomas/kong v0.7.1 h1:azoTh0IOfwlAX3qN9sHWTxACE2oV8Bg2gAwBsMwDQY4= github.com/alecthomas/kong v0.7.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U= github.com/alecthomas/mango-kong v0.1.0 h1:iFVfP1k1K4qpml3JUQmD5I8MCQYfIvsD9mRdrw7jJC4= github.com/alecthomas/mango-kong v0.1.0/go.mod h1:t+TYVdsONUolf/BwVcm+15eqcdAj15h4Qe9MMFAwwT4= -github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE= +github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= -github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/charmbracelet/bubbles v0.15.1-0.20230525133559-6034e6818456 h1:BzIuNg6fFywxp6qI96LH/08uL2Hi9dsqTOqSsRTL6BI= -github.com/charmbracelet/bubbles v0.15.1-0.20230525133559-6034e6818456/go.mod h1:D4UDwNOTGBU2NtVEWtwfhStJO75L8OsqcO7csWH6RrA= github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= -github.com/charmbracelet/bubbletea v0.24.1 h1:LpdYfnu+Qc6XtvMz6d/6rRY71yttHTP5HtrjMgWvixc= -github.com/charmbracelet/bubbletea v0.24.1/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg= -github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= -github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc= -github.com/charmbracelet/glamour v0.6.1-0.20230531150050-63cd3b88ae05 h1:+68qHQWQIn8WsZ0NiKpYlxLPkAEYgq8RkgahsJz3Wqg= -github.com/charmbracelet/glamour v0.6.1-0.20230531150050-63cd3b88ae05/go.mod h1:swCB3CXFsh22H1ESDYdY1tirLiNqCziulDyJ1B6Nt7Q= +github.com/charmbracelet/bubbletea v0.24.2 h1:uaQIKx9Ai6Gdh5zpTbGiWpytMU+CfsPp06RaW2cx/SY= +github.com/charmbracelet/bubbletea v0.24.2/go.mod h1:XdrNrV4J8GiyshTtx3DNuYkR1FDaJmO3l2nejekbsgg= github.com/charmbracelet/glamour v0.6.1-0.20230531150759-6d5b52861a9d h1:S4Ejl/M2VrryIgDrDbiuvkwMUDa67/t/H3Wz3i2/vUw= github.com/charmbracelet/glamour v0.6.1-0.20230531150759-6d5b52861a9d/go.mod h1:swCB3CXFsh22H1ESDYdY1tirLiNqCziulDyJ1B6Nt7Q= github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707 h1:dXv2HjaDlJZj7wLpTjg1P4B68bdvoXfx7+VXF2/RelY= github.com/charmbracelet/lipgloss v0.7.2-0.20230316100548-06dd20ee5707/go.mod h1:BDceYFEeE5FBoGZeuApZ+V4wSgi8AOIHoryyjYbCTHM= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.8.1 h1:6Lcdwya6GjPUNsBct8Lg/yRPwMhABj269AAzdGSiR+0= github.com/dlclark/regexp2 v1.8.1/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -45,7 +32,6 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= @@ -54,7 +40,6 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= 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/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY= github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= @@ -67,46 +52,29 @@ github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/roff v0.1.0 h1:YD0lalCotmYuF5HhZliKWlIx7IEhiXeSfq7hNjFqGF8= github.com/muesli/roff v0.1.0/go.mod h1:pjAHQM9hdUUwm/krAfrLGgJkXJ+YuhtsfZ42kieB2Ig= -github.com/muesli/termenv v0.13.0/go.mod h1:sP1+uffeLaEYpyOTb8pLCUctGcGLnoFjSn4YJK5e2bc= github.com/muesli/termenv v0.15.2-0.20230323153104-73a40463ff25 h1:bgCNxFKF+mM5GxpNvkGleUFt12xOzLOzmMOytttpeK4= github.com/muesli/termenv v0.15.2-0.20230323153104-73a40463ff25/go.mod h1:puu7Fg2fBjAuOzC9hb6zDO/s86uLSYrBlPkIplp2EiA= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y= github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU= github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os= github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ= -golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=