mirror of
https://github.com/charmbracelet/gum.git
synced 2024-09-11 06:16:03 +03:00
feat(choose): keep order of selected items (#182)
* feat(choose): keep order of selected items * fix: KeepOrder -> Ordered Co-authored-by: Maas Lalani <maas@lalani.dev>
This commit is contained in:
parent
832c4fc917
commit
08ed3e2519
@ -30,6 +30,7 @@ type model struct {
|
||||
index int
|
||||
limit int
|
||||
numSelected int
|
||||
currentOrder int
|
||||
paginator paginator.Model
|
||||
aborted bool
|
||||
|
||||
@ -42,6 +43,7 @@ type model struct {
|
||||
type item struct {
|
||||
text string
|
||||
selected bool
|
||||
order int
|
||||
}
|
||||
|
||||
func (m model) Init() tea.Cmd { return nil }
|
||||
@ -96,7 +98,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
continue
|
||||
}
|
||||
m.items[i].selected = true
|
||||
m.items[i].order = m.currentOrder
|
||||
m.numSelected++
|
||||
m.currentOrder++
|
||||
}
|
||||
case "A":
|
||||
if m.limit <= 1 {
|
||||
@ -104,8 +108,10 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
for i := range m.items {
|
||||
m.items[i].selected = false
|
||||
m.items[i].order = 0
|
||||
}
|
||||
m.numSelected = 0
|
||||
m.currentOrder = 0
|
||||
case "ctrl+c", "esc":
|
||||
m.aborted = true
|
||||
m.quitting = true
|
||||
@ -120,7 +126,9 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.numSelected--
|
||||
} else if m.numSelected < m.limit {
|
||||
m.items[m.index].selected = true
|
||||
m.items[m.index].order = m.currentOrder
|
||||
m.numSelected++
|
||||
m.currentOrder++
|
||||
}
|
||||
case "enter":
|
||||
m.quitting = true
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kong"
|
||||
@ -56,10 +57,12 @@ func (o Options) Run() error {
|
||||
hasSelectedItems := len(o.Selected) > 0
|
||||
|
||||
startingIndex := 0
|
||||
currentOrder := 0
|
||||
|
||||
var items = make([]item, len(o.Options))
|
||||
items := make([]item, len(o.Options))
|
||||
|
||||
for i, option := range o.Options {
|
||||
var order int
|
||||
// Check if the option should be selected.
|
||||
isSelected := hasSelectedItems && currentSelected < o.Limit && arrayContains(o.Selected, option)
|
||||
// If the option is selected then increment the current selected count.
|
||||
@ -71,10 +74,12 @@ func (o Options) Run() error {
|
||||
isSelected = false
|
||||
} else {
|
||||
currentSelected++
|
||||
order = currentOrder
|
||||
currentOrder++
|
||||
}
|
||||
}
|
||||
|
||||
items[i] = item{text: option, selected: isSelected}
|
||||
items[i] = item{text: option, selected: isSelected, order: order}
|
||||
}
|
||||
|
||||
// Use the pagination model to display the current and total number of
|
||||
@ -94,6 +99,7 @@ func (o Options) Run() error {
|
||||
|
||||
tm, err := tea.NewProgram(model{
|
||||
index: startingIndex,
|
||||
currentOrder: currentOrder,
|
||||
height: o.Height,
|
||||
cursor: o.Cursor,
|
||||
selectedPrefix: o.SelectedPrefix,
|
||||
@ -117,6 +123,12 @@ func (o Options) Run() error {
|
||||
return exit.ErrAborted
|
||||
}
|
||||
|
||||
if o.Ordered && o.Limit > 1 {
|
||||
sort.Slice(m.items, func(i, j int) bool {
|
||||
return m.items[i].order < m.items[j].order
|
||||
})
|
||||
}
|
||||
|
||||
var s strings.Builder
|
||||
|
||||
for _, item := range m.items {
|
||||
|
@ -8,6 +8,7 @@ type Options struct {
|
||||
|
||||
Limit int `help:"Maximum number of options to pick" default:"1" group:"Selection"`
|
||||
NoLimit bool `help:"Pick unlimited number of options (ignores limit)" group:"Selection"`
|
||||
Ordered bool `help:"Maintain the order of the selected options" env:"GUM_CHOOSE_ORDERED"`
|
||||
Height int `help:"Height of the list" default:"10" env:"GUM_CHOOSE_HEIGHT"`
|
||||
Cursor string `help:"Prefix to show on item that corresponds to the cursor position" default:"> " env:"GUM_CHOOSE_CURSOR"`
|
||||
CursorPrefix string `help:"Prefix to show on the cursor item (hidden if limit is 1)" default:"○ " env:"GUM_CHOOSE_CURSOR_PREFIX"`
|
||||
|
Loading…
Reference in New Issue
Block a user