Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update InteractiveMultiselectPrinter to optionally show selected options #646

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,36 @@
# interactive_multiselect/show_selected_options

```go
package main

import (
"fmt"

"github.com/pterm/pterm"
)

func main() {
// Initialize an empty slice to hold the options.
var options []string

// Populate the options slice with 100 options.
for i := 0; i < 100; i++ {
options = append(options, fmt.Sprintf("Option %d", i))
}

// Add 5 more options to the slice, indicating the availability of fuzzy searching.
for i := 0; i < 5; i++ {
options = append(options, fmt.Sprintf("You can use fuzzy searching (%d)", i))
}

// Use PTerm's interactive multiselect to present the options to the user and capture their selections.
// The Show() method displays the options and waits for user input.
selectedOptions, _ := pterm.DefaultInteractiveMultiselect.
WithOptions(options).
WithShowSelectedOptions(true).
Show()

// Print the selected options, highlighted in green.
pterm.Info.Printfln("Selected options: %s", pterm.Green(selectedOptions))
}
```
27 changes: 27 additions & 0 deletions _examples/interactive_multiselect/show-selected-options/main.go
@@ -0,0 +1,27 @@
package main

import (
"fmt"

"github.com/pterm/pterm"
)

func main() {
// Initialize an empty slice to hold the options.
var options []string

// Populate the options slice with 100 options.
for i := 0; i < 100; i++ {
options = append(options, fmt.Sprintf("Option %d", i))
}

// Use PTerm's interactive multiselect to present the options to the user and capture their selections.
// The Show() method displays the options and waits for user input.
selectedOptions, _ := pterm.DefaultInteractiveMultiselect.
WithOptions(options).
WithShowSelectedOptions(true).
Show()

// Print the selected options, highlighted in green.
pterm.Info.Printfln("Selected options: %s", pterm.Green(selectedOptions))
}
47 changes: 33 additions & 14 deletions interactive_multiselect_printer.go
Expand Up @@ -2,13 +2,15 @@

import (
"fmt"
"sort"

"atomicgo.dev/cursor"
"atomicgo.dev/keyboard"
"atomicgo.dev/keyboard/keys"
"github.com/lithammer/fuzzysearch/fuzzy"

"sort"
"strings"

"github.com/pterm/pterm/internal"
)

Expand All @@ -32,17 +34,18 @@

// InteractiveMultiselectPrinter is a printer for interactive multiselect menus.
type InteractiveMultiselectPrinter struct {
DefaultText string
TextStyle *Style
Options []string
OptionStyle *Style
DefaultOptions []string
MaxHeight int
Selector string
SelectorStyle *Style
Filter bool
Checkmark *Checkmark
OnInterruptFunc func()
DefaultText string
TextStyle *Style
Options []string
OptionStyle *Style
DefaultOptions []string
MaxHeight int
Selector string
SelectorStyle *Style
Filter bool
Checkmark *Checkmark
OnInterruptFunc func()
ShowSelectedOptions bool

selectedOption int
selectedOptions []int
Expand Down Expand Up @@ -110,12 +113,18 @@
return &p
}

// OnInterrupt sets the function to execute on exit of the input reader
// WithOnInterruptFunc sets the function to execute on exit of the input reader
func (p InteractiveMultiselectPrinter) WithOnInterruptFunc(exitFunc func()) *InteractiveMultiselectPrinter {
p.OnInterruptFunc = exitFunc
return &p
}

// WithShowSelectedOptions shows the selected options at the bottom if the menu
func (p InteractiveMultiselectPrinter) WithShowSelectedOptions(b ...bool) *InteractiveMultiselectPrinter {
p.ShowSelectedOptions = internal.WithBoolean(b)
return &p

Check warning on line 125 in interactive_multiselect_printer.go

View check run for this annotation

Codecov / codecov/patch

interactive_multiselect_printer.go#L123-L125

Added lines #L123 - L125 were not covered by tests
}

// Show shows the interactive multiselect menu and returns the selected entry.
func (p *InteractiveMultiselectPrinter) Show(text ...string) ([]string, error) {
// should be the first defer statement to make sure it is executed last
Expand Down Expand Up @@ -379,10 +388,20 @@

help := fmt.Sprintf("%s: %s | %s: %s | left: %s | right: %s", p.KeySelect, Bold.Sprint("select"), p.KeyConfirm, Bold.Sprint("confirm"), Bold.Sprint("none"), Bold.Sprint("all"))
if p.Filter {
help += fmt.Sprintf("| type to %s", Bold.Sprint("filter"))
help += fmt.Sprintf(" | type to %s", Bold.Sprint("filter"))
}
content += ThemeDefault.SecondaryStyle.Sprintfln(help)

// Optionally, add selected options to the menu
if p.ShowSelectedOptions && len(p.selectedOptions) > 0 {
selected := make([]string, len(p.selectedOptions))
for i, optIdx := range p.selectedOptions {
selected[i] = p.Options[optIdx]
}

Check warning on line 400 in interactive_multiselect_printer.go

View check run for this annotation

Codecov / codecov/patch

interactive_multiselect_printer.go#L397-L400

Added lines #L397 - L400 were not covered by tests

content += ThemeDefault.SecondaryStyle.Sprint("Selected: ") + Green(strings.Join(selected, Gray(", "))) + "\n"

Check warning on line 402 in interactive_multiselect_printer.go

View check run for this annotation

Codecov / codecov/patch

interactive_multiselect_printer.go#L402

Added line #L402 was not covered by tests
}

return content
}

Expand Down