mirror of https://github.com/charmbracelet/gum
docs: document gum table, file, pager
This commit documents `gum table`, `gum file`, and `gum pager` with demonstration GIFs and sample scripts.
This commit is contained in:
parent
2bea4dc030
commit
995bd04e38
42
README.md
42
README.md
|
@ -289,6 +289,34 @@ gum confirm && rm file.txt || echo "File not removed"
|
|||
<img src="https://stuff.charm.sh/gum/confirm_2.gif" alt="Shell running gum confirm" />
|
||||
</picture>
|
||||
|
||||
#### File
|
||||
|
||||
Prompt the user to select a file from the file tree.
|
||||
|
||||
```bash
|
||||
EDITOR $(gum file $HOME)
|
||||
```
|
||||
|
||||
<picture>
|
||||
<source media="(max-width: 600px)" srcset="https://stuff.charm.sh/gum/file.gif">
|
||||
<source media="(min-width: 600px)" width="600" srcset="https://stuff.charm.sh/gum/file.gif">
|
||||
<img src="https://stuff.charm.sh/gum/file.gif" alt="Shell running gum file" />
|
||||
</picture>
|
||||
|
||||
#### Pager
|
||||
|
||||
Scroll through a long document with line numbers and a fully customizable viewport.
|
||||
|
||||
```bash
|
||||
gum pager < README.md
|
||||
```
|
||||
|
||||
<picture>
|
||||
<source media="(max-width: 600px)" srcset="https://stuff.charm.sh/gum/pager.gif">
|
||||
<source media="(min-width: 600px)" width="600" srcset="https://stuff.charm.sh/gum/pager.gif">
|
||||
<img src="https://stuff.charm.sh/gum/pager.gif" alt="Shell running gum pager" />
|
||||
</picture>
|
||||
|
||||
#### Spin
|
||||
|
||||
Display a spinner while running a script or command. The spinner will
|
||||
|
@ -306,6 +334,20 @@ gum spin --spinner dot --title "Buying Bubble Gum..." -- sleep 5
|
|||
|
||||
Available spinner types include: `line`, `dot`, `minidot`, `jump`, `pulse`, `points`, `globe`, `moon`, `monkey`, `meter`, `hamburger`.
|
||||
|
||||
#### Table
|
||||
|
||||
Select a row from some tabular data.
|
||||
|
||||
```bash
|
||||
gum table < flavors.csv | cut -d ',' -f 1
|
||||
```
|
||||
|
||||
<picture>
|
||||
<source media="(max-width: 600px)" srcset="https://stuff.charm.sh/gum/table.gif">
|
||||
<source media="(min-width: 600px)" width="600" srcset="https://stuff.charm.sh/gum/table.gif">
|
||||
<img src="https://stuff.charm.sh/gum/table.gif" alt="Shell running gum table" />
|
||||
</picture>
|
||||
|
||||
## Styling
|
||||
|
||||
#### Style
|
||||
|
|
|
@ -17,7 +17,7 @@ func (o Options) Run() error {
|
|||
|
||||
path, err := filepath.Abs(o.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("file not found: %w", err)
|
||||
}
|
||||
|
||||
m := model{
|
||||
|
@ -43,7 +43,7 @@ func (o Options) Run() error {
|
|||
|
||||
tm, err := tea.NewProgram(&m, tea.WithOutput(os.Stderr)).StartReturningModel()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("unable to pick selection: %w", err)
|
||||
}
|
||||
|
||||
m = tm.(model)
|
||||
|
|
32
file/file.go
32
file/file.go
|
@ -196,30 +196,34 @@ func (m model) View() string {
|
|||
isSymlink := info.Mode()&fs.ModeSymlink != 0
|
||||
size := humanize.Bytes(uint64(info.Size()))
|
||||
name := f.Name()
|
||||
|
||||
if isSymlink {
|
||||
symlinkPath, _ = filepath.EvalSymlinks(filepath.Join(m.path, name))
|
||||
}
|
||||
|
||||
if m.selected == i {
|
||||
selected := fmt.Sprintf(" %s %"+fmt.Sprint(m.fileSizeStyle.GetWidth())+"s %s", info.Mode().String(), size, name)
|
||||
if isSymlink {
|
||||
selected = fmt.Sprintf("%s → %s", selected, symlinkPath)
|
||||
}
|
||||
s.WriteString(m.cursorStyle.Render(m.cursor) + m.selectedStyle.Render(selected))
|
||||
} else {
|
||||
var style = m.fileStyle
|
||||
if f.IsDir() {
|
||||
style = m.directoryStyle
|
||||
} else if isSymlink {
|
||||
style = m.symlinkStyle
|
||||
}
|
||||
|
||||
fileName := style.Render(name)
|
||||
if isSymlink {
|
||||
fileName = fmt.Sprintf("%s → %s", fileName, symlinkPath)
|
||||
}
|
||||
s.WriteString(fmt.Sprintf(" %s %s %s", m.permissionStyle.Render(info.Mode().String()), m.fileSizeStyle.Render(size), fileName))
|
||||
s.WriteRune('\n')
|
||||
continue
|
||||
}
|
||||
s.WriteString("\n")
|
||||
|
||||
var style = m.fileStyle
|
||||
if f.IsDir() {
|
||||
style = m.directoryStyle
|
||||
} else if isSymlink {
|
||||
style = m.symlinkStyle
|
||||
}
|
||||
|
||||
fileName := style.Render(name)
|
||||
if isSymlink {
|
||||
fileName = fmt.Sprintf("%s → %s", fileName, symlinkPath)
|
||||
}
|
||||
s.WriteString(fmt.Sprintf(" %s %s %s", m.permissionStyle.Render(info.Mode().String()), m.fileSizeStyle.Render(size), fileName))
|
||||
s.WriteRune('\n')
|
||||
}
|
||||
|
||||
return s.String()
|
||||
|
|
|
@ -4,7 +4,7 @@ package file
|
|||
|
||||
import "strings"
|
||||
|
||||
// IsHidden reports whether a file is hidden or not
|
||||
// IsHidden reports whether a file is hidden or not.
|
||||
func IsHidden(file string) (bool, error) {
|
||||
return strings.HasPrefix(file, "."), nil
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ type Options struct {
|
|||
DirectoryStyle style.Styles `embed:"" prefix:"directory." help:"The style to use for directories" set:"defaultForeground=99" envprefix:"GUM_FILE_DIRECTORY_"`
|
||||
FileStyle style.Styles `embed:"" prefix:"file." help:"The style to use for files" envprefix:"GUM_FILE_FILE_"`
|
||||
PermissionsStyle style.Styles `embed:"" prefix:"permissions." help:"The style to use for permissions" set:"defaultForeground=244" envprefix:"GUM_FILE_PERMISSIONS_"`
|
||||
SelectedStyle style.Styles `embed:"" prefix:"selected." help:"The style to use for the selected item" set:"defaultBold=true" set:"defaultForeground=212" envprefix:"GUM_FILE_SELECTED_"`
|
||||
FileSizeStyle style.Styles `embed:"" prefix:"file-size." help:"The style to use for file sizes" set:"defaultWidth=8" set:"defaultAlign=right" set:"defaultForeground=240" envprefix:"GUM_FILE_FILE_SIZE_"`
|
||||
//nolint:staticcheck
|
||||
SelectedStyle style.Styles `embed:"" prefix:"selected." help:"The style to use for the selected item" set:"defaultBold=true" set:"defaultForeground=212" envprefix:"GUM_FILE_SELECTED_"`
|
||||
//nolint:staticcheck
|
||||
FileSizeStyle style.Styles `embed:"" prefix:"file-size." help:"The style to use for file sizes" set:"defaultWidth=8" set:"defaultAlign=right" set:"defaultForeground=240" envprefix:"GUM_FILE_FILE_SIZE_"`
|
||||
}
|
||||
|
|
16
go.sum
16
go.sum
|
@ -13,23 +13,15 @@ github.com/aymanbagabas/go-osc52 v1.0.3 h1:DTwqENW7X9arYimJrPeGZcV0ln14sGMt3pHZs
|
|||
github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
|
||||
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.14.0 h1:DJfCwnARfWjZLvMglhSQzo76UZ2gucuHPy9jLWX45Og=
|
||||
github.com/charmbracelet/bubbles v0.14.0/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWoiNibae+1yCMtcc=
|
||||
github.com/charmbracelet/bubbletea v0.21.0/go.mod h1:GgmJMec61d08zXsOhqRC/AiOx4K4pmz+VIcRIm1FKr4=
|
||||
github.com/charmbracelet/bubbletea v0.22.1 h1:z66q0LWdJNOWEH9zadiAIXp2GN1AWrwNXU8obVY9X24=
|
||||
github.com/charmbracelet/bubbles v0.14.1-0.20221006154229-d1775121146a h1:/prXWlDbR4CWT1FaTvkU8WhLfpZv3eOrN9PtL8oDdDU=
|
||||
github.com/charmbracelet/bubbles v0.14.1-0.20221006154229-d1775121146a/go.mod h1:5rZgJTHmgWISQnxnzzIJtQt3GC1bfJfNmr4SEtRDtTQ=
|
||||
github.com/charmbracelet/bubbletea v0.22.1/go.mod h1:8/7hVvbPN6ZZPkczLiB8YpLkLJ0n7DMho5Wvfd2X1C0=
|
||||
<<<<<<< HEAD
|
||||
github.com/charmbracelet/bubbletea v0.22.2-0.20221007181357-2696b2f3399f h1:mbSd0Sdm2wXUWtXJ81o86G9V+9IhddX0qQcGK6bMbKo=
|
||||
github.com/charmbracelet/bubbletea v0.22.2-0.20221007181357-2696b2f3399f/go.mod h1:JAfGK/3/pPKHTnAS8JIE2u9f61BjWTQY57RbT25aMXU=
|
||||
||||||| parent of c5917c0 (feat(file): gum file to pick files)
|
||||
github.com/charmbracelet/bubbletea v0.22.2-0.20221006105051-f406999cba69 h1:GpZktjqyEQjuvFtFb0UlMlbZCOwOhk/bpKb6+quLz+E=
|
||||
github.com/charmbracelet/bubbletea v0.22.2-0.20221006105051-f406999cba69/go.mod h1:JAfGK/3/pPKHTnAS8JIE2u9f61BjWTQY57RbT25aMXU=
|
||||
=======
|
||||
>>>>>>> c5917c0 (feat(file): gum file to pick files)
|
||||
github.com/charmbracelet/glamour v0.5.1-0.20220727184942-e70ff2d969da h1:FGz53GWQRiKQ/5xUsoCCkewSQIC7u81Scaxx2nUy3nM=
|
||||
github.com/charmbracelet/glamour v0.5.1-0.20220727184942-e70ff2d969da/go.mod h1:HXz79SMFnF9arKxqeoHWxmo1BhplAH7wehlRhKQIL94=
|
||||
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
|
||||
github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs=
|
||||
github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk=
|
||||
github.com/charmbracelet/lipgloss v0.6.1-0.20220930064401-ae7c84f7b158 h1:uuY3ti70rfEiLw3rHKSRiJ+cWfq4KWScgjxhoVRf0eE=
|
||||
github.com/charmbracelet/lipgloss v0.6.1-0.20220930064401-ae7c84f7b158/go.mod h1:5EY1dcRQX7kPSA5ssoYjq2qEDhpS4cdtmdYY1OlAdMs=
|
||||
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
||||
|
@ -62,7 +54,6 @@ github.com/microcosm-cc/bluemonday v1.0.19 h1:OI7hoF5FY4pFz2VA//RN8TfM0YJ2dJcl4P
|
|||
github.com/microcosm-cc/bluemonday v1.0.19/go.mod h1:QNzV2UbLK2/53oIIwTOyLUSABMkjZ4tqiyC1g/DyqxE=
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34=
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
||||
github.com/muesli/cancelreader v0.2.0/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||
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.1.1-0.20220205060214-77e2058169ab h1:m7QFONkzLK0fVXCjwX5tANcnj1yXxTnYQtnfJiY3tcA=
|
||||
|
@ -107,7 +98,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
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-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
|
|
|
@ -7,7 +7,7 @@ type Stack struct {
|
|||
Length func() int
|
||||
}
|
||||
|
||||
// NewStack returns a new stack of integers
|
||||
// NewStack returns a new stack of integers.
|
||||
func NewStack() Stack {
|
||||
slice := make([]int, 0)
|
||||
return Stack{
|
||||
|
|
|
@ -13,12 +13,11 @@ import (
|
|||
func (o Options) Run() error {
|
||||
vp := viewport.New(o.Style.Width, o.Style.Height)
|
||||
vp.Style = o.Style.ToLipgloss()
|
||||
var err error
|
||||
|
||||
if o.Content == "" {
|
||||
stdin, err := stdin.Read()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("unable to read stdin")
|
||||
}
|
||||
if stdin != "" {
|
||||
o.Content = stdin
|
||||
|
@ -34,9 +33,9 @@ func (o Options) Run() error {
|
|||
showLineNumbers: o.ShowLineNumbers,
|
||||
lineNumberStyle: o.LineNumberStyle.ToLipgloss(),
|
||||
}
|
||||
err := tea.NewProgram(model, tea.WithAltScreen()).Start()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("unable to start program: %w", err)
|
||||
}
|
||||
|
||||
return tea.NewProgram(model, tea.WithAltScreen()).Start()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ 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"`
|
||||
|
|
|
@ -28,7 +28,7 @@ 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 - 2
|
||||
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
|
||||
|
|
|
@ -15,11 +15,11 @@ import (
|
|||
"github.com/charmbracelet/gum/style"
|
||||
)
|
||||
|
||||
// Run provides a shell script interface for rendering tabular data (CSV)
|
||||
// Run provides a shell script interface for rendering tabular data (CSV).
|
||||
func (o Options) Run() error {
|
||||
var reader *csv.Reader
|
||||
if o.File != "" {
|
||||
file, err := os.OpenFile(o.File, os.O_RDONLY, 0600)
|
||||
file, err := os.Open(o.File)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not find file at path %s", o.File)
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ func (o Options) Run() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("invalid data provided")
|
||||
}
|
||||
var columns []table.Column
|
||||
var columns = make([]table.Column, 0, len(columnNames))
|
||||
|
||||
for i, title := range columnNames {
|
||||
width := runewidth.StringWidth(title)
|
||||
|
@ -75,7 +75,7 @@ func (o Options) Run() error {
|
|||
Selected: defaultStyles.Selected.Inherit(o.SelectedStyle.ToLipgloss()),
|
||||
}
|
||||
|
||||
var rows []table.Row
|
||||
var rows = make([]table.Row, 0, len(data))
|
||||
for _, row := range data {
|
||||
rows = append(rows, table.Row(row))
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ func (o Options) Run() error {
|
|||
}
|
||||
|
||||
m := tm.(model)
|
||||
fmt.Println(strings.Join([]string(m.selected), string(o.Separator)))
|
||||
fmt.Println(strings.Join([]string(m.selected), o.Separator))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -8,11 +8,10 @@
|
|||
//
|
||||
// $ gum table <<< "Flavor,Price\nStrawberry,$0.50\nBanana,$0.99\nCherry,$0.75"
|
||||
//
|
||||
// Flavor Price
|
||||
// Strawberry $0.50
|
||||
// Banana $0.99
|
||||
// Cherry $0.75
|
||||
//
|
||||
// Flavor Price
|
||||
// Strawberry $0.50
|
||||
// Banana $0.99
|
||||
// Cherry $0.75
|
||||
package table
|
||||
|
||||
import (
|
||||
|
|
Loading…
Reference in New Issue