mirror of
https://github.com/charmbracelet/gum
synced 2024-05-17 05:36:42 +02:00
feat: gum confirm
This commit is contained in:
parent
483da45749
commit
108a680385
30
confirm/command.go
Normal file
30
confirm/command.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package confirm
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
// Run provides a shell script interface for prompting a user to confirm an
|
||||
// action with an affirmative or negative answer.
|
||||
func (o Options) Run() error {
|
||||
m, err := tea.NewProgram(model{
|
||||
affirmative: o.Affirmative,
|
||||
negative: o.Negative,
|
||||
vertical: o.Vertical,
|
||||
selected: 0,
|
||||
prompt: o.Prompt,
|
||||
selectedStyle: o.SelectedStyle.ToLipgloss(),
|
||||
unselectedStyle: o.UnselectedStyle.ToLipgloss(),
|
||||
promptStyle: o.PromptStyle.ToLipgloss(),
|
||||
}, tea.WithOutput(os.Stderr)).StartReturningModel()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
os.Exit(m.(model).selected)
|
||||
|
||||
return nil
|
||||
}
|
84
confirm/confirm.go
Normal file
84
confirm/confirm.go
Normal file
|
@ -0,0 +1,84 @@
|
|||
// Package confirm provides an interface to ask a user to confirm an action.
|
||||
// The user is provided with an interface to choose an affirmative or negative
|
||||
// answer, which is then reflected in the exit code for use in scripting.
|
||||
//
|
||||
// If the user selects the affirmative answer, the program exits with 0. If the
|
||||
// user selects the negative answer, the program exits with 1.
|
||||
//
|
||||
// I.e. confirm if the user wants to delete a file
|
||||
//
|
||||
// $ gum confirm "Are you sure?" && rm file.txt
|
||||
//
|
||||
package confirm
|
||||
|
||||
import (
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
type model struct {
|
||||
prompt string
|
||||
affirmative string
|
||||
negative string
|
||||
vertical bool
|
||||
quitting bool
|
||||
selected int
|
||||
|
||||
// styles
|
||||
promptStyle lipgloss.Style
|
||||
selectedStyle lipgloss.Style
|
||||
unselectedStyle lipgloss.Style
|
||||
}
|
||||
|
||||
func (m model) Init() tea.Cmd { return nil }
|
||||
|
||||
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
switch msg := msg.(type) {
|
||||
case tea.WindowSizeMsg:
|
||||
return m, nil
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "left", "h", "ctrl+p":
|
||||
m.selected = m.selected - 1
|
||||
if m.selected < 0 {
|
||||
m.selected = 1
|
||||
}
|
||||
case "right", "l", "ctrl+n":
|
||||
m.selected = m.selected + 1
|
||||
if m.selected > 1 {
|
||||
m.selected = 0
|
||||
}
|
||||
case "enter":
|
||||
m.quitting = true
|
||||
return m, tea.Quit
|
||||
case "ctrl+c", "q":
|
||||
m.selected = 1
|
||||
m.quitting = true
|
||||
return m, tea.Quit
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m model) View() string {
|
||||
if m.quitting {
|
||||
return ""
|
||||
}
|
||||
|
||||
joinFunc := lipgloss.JoinHorizontal
|
||||
if m.vertical {
|
||||
joinFunc = lipgloss.JoinVertical
|
||||
}
|
||||
|
||||
var aff, neg string
|
||||
|
||||
if m.selected == 0 {
|
||||
aff = m.selectedStyle.Render(m.affirmative)
|
||||
neg = m.unselectedStyle.Render(m.negative)
|
||||
} else {
|
||||
aff = m.unselectedStyle.Render(m.affirmative)
|
||||
neg = m.selectedStyle.Render(m.negative)
|
||||
}
|
||||
|
||||
return lipgloss.JoinVertical(lipgloss.Center, m.promptStyle.Render(m.prompt), joinFunc(lipgloss.Left, aff, neg))
|
||||
}
|
14
confirm/options.go
Normal file
14
confirm/options.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
package confirm
|
||||
|
||||
import "github.com/charmbracelet/gum/style"
|
||||
|
||||
// Options is the customization options for the confirm command.
|
||||
type Options struct {
|
||||
Affirmative string `help:"The title of the affirmative action" default:"Yes"`
|
||||
Negative string `help:"The title of the negative action" default:"No"`
|
||||
Prompt string `arg:"" help:"Prompt to display." default:"Are you sure?"`
|
||||
Vertical bool `help:"Whether to display the options vertically" default:"false"`
|
||||
PromptStyle style.Styles `embed:"" prefix:"prompt." help:"The style of the prompt"`
|
||||
UnselectedStyle style.Styles `embed:"" prefix:"unselected." help:"The style of the unselected action" set:"defaultBackground=0" set:"defaultPadding=0 3" set:"defaultMargin=1 1"`
|
||||
SelectedStyle style.Styles `embed:"" prefix:"selected." help:"The style of the selected action" set:"defaultBackground=8" set:"defaultForeground=212" set:"defaultPadding=0 3" set:"defaultMargin=1 1"`
|
||||
}
|
15
gum.go
15
gum.go
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"github.com/charmbracelet/gum/choose"
|
||||
"github.com/charmbracelet/gum/completion"
|
||||
"github.com/charmbracelet/gum/confirm"
|
||||
"github.com/charmbracelet/gum/filter"
|
||||
"github.com/charmbracelet/gum/format"
|
||||
"github.com/charmbracelet/gum/input"
|
||||
|
@ -34,6 +35,20 @@ type Gum struct {
|
|||
//
|
||||
Choose choose.Options `cmd:"" help:"Choose an option from a list of choices"`
|
||||
|
||||
// Confirm provides an interface to ask a user to confirm an action.
|
||||
// The user is provided with an interface to choose an affirmative or
|
||||
// negative answer, which is then reflected in the exit code for use in
|
||||
// scripting.
|
||||
//
|
||||
// If the user selects the affirmative answer, the program exits with 0.
|
||||
// If the user selects the negative answer, the program exits with 1.
|
||||
//
|
||||
// I.e. confirm if the user wants to delete a file
|
||||
//
|
||||
// $ gum confirm "Are you sure?" && rm file.txt
|
||||
//
|
||||
Confirm confirm.Options `cmd:"" help:"Ask a user to confirm an action"`
|
||||
|
||||
// Filter provides a fuzzy searching text input to allow filtering a list of
|
||||
// options to select one option.
|
||||
//
|
||||
|
|
3
main.go
3
main.go
|
@ -25,6 +25,9 @@ func main() {
|
|||
kong.Vars{
|
||||
"defaultBackground": "",
|
||||
"defaultForeground": "",
|
||||
"defaultMargin": "0 0",
|
||||
"defaultPadding": "0 0",
|
||||
"defaultUnderline": "false",
|
||||
},
|
||||
)
|
||||
ctx.Run()
|
||||
|
|
|
@ -22,5 +22,6 @@ func (s Styles) ToLipgloss() lipgloss.Style {
|
|||
Bold(s.Bold).
|
||||
Faint(s.Faint).
|
||||
Italic(s.Italic).
|
||||
Strikethrough(s.Strikethrough)
|
||||
Strikethrough(s.Strikethrough).
|
||||
Underline(s.Underline)
|
||||
}
|
||||
|
|
|
@ -18,24 +18,25 @@ type Options struct {
|
|||
// components, through embedding and prefixing.
|
||||
type Styles struct {
|
||||
// Colors
|
||||
Background string `help:"Background color of the ${name=element}" default:"${defaultBackground}" group:"Style Flags"`
|
||||
Foreground string `help:"color of the ${name=element}" default:"${defaultForeground}" group:"Style Flags"`
|
||||
Background string `help:"Background Color" default:"${defaultBackground}" group:"Style Flags"`
|
||||
Foreground string `help:"Foreground Color" default:"${defaultForeground}" group:"Style Flags"`
|
||||
|
||||
// Border
|
||||
Border string `help:"Border style to apply" enum:"none,hidden,normal,rounded,thick,double" default:"none" group:"Style Flags"`
|
||||
BorderBackground string `help:"Border background color" group:"Style Flags"`
|
||||
BorderForeground string `help:"Border foreground color" group:"Style Flags"`
|
||||
Border string `help:"Border Style" enum:"none,hidden,normal,rounded,thick,double" default:"none" group:"Style Flags"`
|
||||
BorderBackground string `help:"Border Background Color" group:"Style Flags"`
|
||||
BorderForeground string `help:"Border Foreground Color" group:"Style Flags"`
|
||||
|
||||
// Layout
|
||||
Align string `help:"Text alignment" enum:"left,center,right,bottom,middle,top" default:"left" group:"Style Flags"`
|
||||
Height int `help:"Height of output" group:"Style Flags"`
|
||||
Width int `help:"Width of output" group:"Style Flags"`
|
||||
Margin string `help:"Margin to apply around the text." default:"0 0" group:"Style Flags"`
|
||||
Padding string `help:"Padding to apply around the text." default:"0 0"`
|
||||
Align string `help:"Text Alignment" enum:"left,center,right,bottom,middle,top" default:"left" group:"Style Flags"`
|
||||
Height int `help:"Text height" group:"Style Flags"`
|
||||
Width int `help:"Text width" group:"Style Flags"`
|
||||
Margin string `help:"Text margin" default:"${defaultMargin}" group:"Style Flags"`
|
||||
Padding string `help:"Text padding" default:"${defaultPadding}" group:"Style Flags"`
|
||||
|
||||
// Format
|
||||
Bold bool `help:"Apply bold formatting" group:"Style Flags"`
|
||||
Faint bool `help:"Apply faint formatting" group:"Style Flags"`
|
||||
Italic bool `help:"Apply italic formatting" group:"Style Flags"`
|
||||
Strikethrough bool `help:"Apply strikethrough formatting" group:"Style Flags"`
|
||||
Bold bool `help:"Bold text" group:"Style Flags"`
|
||||
Faint bool `help:"Faint text" group:"Style Flags"`
|
||||
Italic bool `help:"Italicize text" group:"Style Flags"`
|
||||
Strikethrough bool `help:"Strikethrough text" group:"Style Flags"`
|
||||
Underline bool `help:"Underline text" default:"${defaultUnderline}" group:"Style Flags"`
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue