API
simpleinput
import "github.com/aschey/bubbleprompt/input/simpleinput"
Package simpleinput provides an implementation of the input.Input interface. It should be used for basic cases without the need for structured or cli-style input
Example
package main
import (
"fmt"
"os"
"strconv"
prompt "github.com/aschey/bubbleprompt"
"github.com/aschey/bubbleprompt/completer"
"github.com/aschey/bubbleprompt/executor"
"github.com/aschey/bubbleprompt/input/simpleinput"
"github.com/aschey/bubbleprompt/suggestion"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
type model struct {
suggestions []suggestion.Suggestion[any]
textInput *simpleinput.Model[any]
outputStyle lipgloss.Style
numChoices int64
filterer completer.Filterer[any]
}
func (m model) Complete(promptModel prompt.Model[any]) ([]suggestion.Suggestion[any], error) {
if len(m.textInput.Tokens()) > 1 {
return nil, nil
}
return m.filterer.Filter(m.textInput.CurrentTokenBeforeCursor(), m.suggestions), nil
}
func (m model) Execute(input string, promptModel *prompt.Model[any]) (tea.Model, error) {
tokens := m.textInput.WordTokenValues()
if len(tokens) == 0 {
return nil, fmt.Errorf("No selection")
}
return executor.NewStringModel(m.formatOutput(tokens[0])), nil
}
func (m model) formatOutput(choice string) string {
return fmt.Sprintf("You picked: %s\nYou've entered %s submissions(s)\n\n",
m.outputStyle.Render(choice),
m.outputStyle.Render(strconv.FormatInt(m.numChoices, 10)))
}
func (m model) Init() tea.Cmd {
return nil
}
func (m model) Update(msg tea.Msg) (prompt.InputHandler[any], tea.Cmd) {
if msg, ok := msg.(tea.KeyMsg); ok && msg.Type == tea.KeyEnter {
m.numChoices++
}
return m, nil
}
func main() {
// Initialize the input
textInput := simpleinput.New[any]()
// Define our suggestions
suggestions := []suggestion.Suggestion[any]{
{Text: "banana", Description: "good with peanut butter"},
{Text: "\"sugar apple\"", SuggestionText: "sugar apple", Description: "spherical...ish"},
{Text: "jackfruit", Description: "the jack of all fruits"},
{Text: "snozzberry", Description: "tastes like snozzberries"},
{Text: "lychee", Description: "better than leeches"},
{Text: "mangosteen", Description: "it's not a mango"},
{Text: "durian", Description: "stinky"},
}
// Combine everything into our model
model := model{
suggestions: suggestions,
textInput: textInput,
// Add some coloring to the foreground of our output to make it look pretty
outputStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("13")),
filterer: completer.NewPrefixFilter[any](),
}
// Create the Bubbleprompt model
// This struct fulfills the tea.Model interface so it can be passed directly to tea.NewProgram
promptModel := prompt.New[any](model, textInput)
fmt.Println(lipgloss.NewStyle().Foreground(lipgloss.Color("6")).Render("Pick a fruit!"))
fmt.Println()
if _, err := tea.NewProgram(promptModel, tea.WithFilter(prompt.MsgFilter)).Run(); err != nil {
fmt.Printf("Could not start program\n%v\n", err)
os.Exit(1)
}
}
Index
- type Model
- func New[T any](options ...Option[T]) *Model[T]
- func (m *Model[T]) Blur()
- func (m *Model[T]) CurrentToken() input.Token
- func (m *Model[T]) CurrentTokenBeforeCursor() string
- func (m *Model[T]) CurrentTokenRoundDown() input.Token
- func (m *Model[T]) CursorIndex() int
- func (m *Model[T]) CursorOffset() int
- func (m *Model[T]) Focus() tea.Cmd
- func (m *Model[T]) Focused() bool
- func (m *Model[T]) OnExecutorFinished()
- func (m *Model[T]) OnSuggestionChanged(suggestion suggestion.Suggestion[T])
- func (m *Model[T]) OnSuggestionUnselected()
- func (m *Model[T]) OnUpdateFinish(msg tea.Msg, suggestion *suggestion.Suggestion[T], isSelected bool) tea.Cmd
- func (m *Model[T]) OnUpdateStart(msg tea.Msg) tea.Cmd
- func (m *Model[T]) Prompt() string
- func (m *Model[T]) ResetValue()
- func (m *Model[T]) Runes() []rune
- func (m *Model[T]) SetCursor(cursor int)
- func (m *Model[T]) SetCursorMode(cursorMode cursor.Mode) tea.Cmd
- func (m *Model[T]) SetPrompt(prompt string)
- func (m *Model[T]) SetValue(value string)
- func (m *Model[T]) ShouldClearSuggestions(prevText []rune, msg tea.KeyMsg) bool
- func (m *Model[T]) ShouldSelectSuggestion(suggestion suggestion.Suggestion[T]) bool
- func (m *Model[T]) ShouldUnselectSuggestion(prevText []rune, msg tea.KeyMsg) bool
- func (m *Model[T]) SuggestionRunes(runes []rune) []rune
- func (m *Model[T]) Tokens() []input.Token
- func (m *Model[T]) TokensBeforeCursor() []input.Token
- func (m *Model[T]) Value() string
- func (m *Model[T]) View(viewMode input.ViewMode) string
- func (m *Model[T]) WordTokenValues() []string
- func (m *Model[T]) WordTokens() []input.Token
- func (m *Model[T]) WordTokensBeforeCursor() []input.Token
- type Option
- func WithCursorMode[T any](cursorMode cursor.Mode) Option[T]
- func WithDelimiterRegex[T any](delimiterRegex string) Option[T]
- func WithFormatter[T any](formatterFunc func(lexer parser.Lexer) parser.Formatter) Option[T]
- func WithPrompt[T any](prompt string) Option[T]
- func WithSelectedTextStyle[T any](style lipgloss.Style) Option[T]
- func WithTokenRegex[T any](tokenRegex string) Option[T]
type Model
A Model is an input for handling simple token-based inputs without any special parsing required.
type Model[T any] struct {
// contains filtered or unexported fields
}
func New
func New[T any](options ...Option[T]) *Model[T]
New creates new a model.
func (*Model[T]) Blur
func (m *Model[T]) Blur()
Blur removes the focus from the input.
func (*Model[T]) CurrentToken
func (m *Model[T]) CurrentToken() input.Token
CurrentToken returns the token under the cursor.
func (*Model[T]) CurrentTokenBeforeCursor
func (m *Model[T]) CurrentTokenBeforeCursor() string
CurrentTokenBeforeCursor returns the portion of the token under the cursor that comes before the cursor position.
func (*Model[T]) CurrentTokenRoundDown
func (m *Model[T]) CurrentTokenRoundDown() input.Token
func (*Model[T]) CursorIndex
func (m *Model[T]) CursorIndex() int
CursorIndex returns the cursor index in terms of number of unicode characters. Use this to calculate input lengths in terms of number of characters entered.
func (*Model[T]) CursorOffset
func (m *Model[T]) CursorOffset() int
CursorOffset returns the visual offset of the cursor in terms of number of terminal cells. Use this for calculating visual dimensions such as input width/height.
func (*Model[T]) Focus
func (m *Model[T]) Focus() tea.Cmd
Focus sets the keyboard focus on the editor so the user can enter text.
func (*Model[T]) Focused
func (m *Model[T]) Focused() bool
Focused returns whether the keyboard is focused on the input.
func (*Model[T]) OnExecutorFinished
func (m *Model[T]) OnExecutorFinished()
OnExecutorFinished is part of the input.Input interface. It should not be invoked by users of this library.
func (*Model[T]) OnSuggestionChanged
func (m *Model[T]) OnSuggestionChanged(suggestion suggestion.Suggestion[T])
OnSuggestionChanged is part of the input.Input interface. It should not be invoked by users of this library.
func (*Model[T]) OnSuggestionUnselected
func (m *Model[T]) OnSuggestionUnselected()
OnSuggestionUnselected is part of the input.Input interface. It should not be invoked by users of this library.
func (*Model[T]) OnUpdateFinish
func (m *Model[T]) OnUpdateFinish(msg tea.Msg, suggestion *suggestion.Suggestion[T], isSelected bool) tea.Cmd
OnUpdateFinish is part of the input.Input interface. It should not be invoked by users of this library.
func (*Model[T]) OnUpdateStart
func (m *Model[T]) OnUpdateStart(msg tea.Msg) tea.Cmd
OnUpdateStart is part of the input.Input interface. It should not be invoked by end users.
func (*Model[T]) Prompt
func (m *Model[T]) Prompt() string
Prompt returns the terminal prompt.
func (*Model[T]) ResetValue
func (m *Model[T]) ResetValue()
ResetValue clears the input.
func (*Model[T]) Runes
func (m *Model[T]) Runes() []rune
Runes returns the raw text entered by the user as a list of runes. This is useful for indexing and length checks because doing these operations on strings does not work well with some unicode characters.
func (*Model[T]) SetCursor
func (m *Model[T]) SetCursor(cursor int)
SetCursor sets the cursor position.
func (*Model[T]) SetCursorMode
func (m *Model[T]) SetCursorMode(cursorMode cursor.Mode) tea.Cmd
SetCursorMode sets the mode of the cursor.
func (*Model[T]) SetPrompt
func (m *Model[T]) SetPrompt(prompt string)
SetPrompt sets the terminal prompt.
func (*Model[T]) SetValue
func (m *Model[T]) SetValue(value string)
SetValue sets the text of the input.
func (*Model[T]) ShouldClearSuggestions
func (m *Model[T]) ShouldClearSuggestions(prevText []rune, msg tea.KeyMsg) bool
ShouldClearSuggestions is part of the input.Input interface. It should not be invoked by users of this library.
func (*Model[T]) ShouldSelectSuggestion
func (m *Model[T]) ShouldSelectSuggestion(suggestion suggestion.Suggestion[T]) bool
ShouldSelectSuggestion is part of the input.Input interface. It should not be invoked by users of this library.
func (*Model[T]) ShouldUnselectSuggestion
func (m *Model[T]) ShouldUnselectSuggestion(prevText []rune, msg tea.KeyMsg) bool
ShouldUnselectSuggestion is part of the input.Input interface. It should not be invoked by users of this library.
func (*Model[T]) SuggestionRunes
func (m *Model[T]) SuggestionRunes(runes []rune) []rune
SuggestionRunes is part of the input.Input interface. It should not be invoked by users of this library.
func (*Model[T]) Tokens
func (m *Model[T]) Tokens() []input.Token
Tokens returns the tokenized input. This includes delimiter tokens.
func (*Model[T]) TokensBeforeCursor
func (m *Model[T]) TokensBeforeCursor() []input.Token
TokensBeforeCursor returns the tokenized input up to the cursor position. This includes delimiter tokens.
func (*Model[T]) Value
func (m *Model[T]) Value() string
Value returns the raw text entered by the user.
func (*Model[T]) View
func (m *Model[T]) View(viewMode input.ViewMode) string
View is part of the input.Input interface. It should not be invoked by users of this library.
func (*Model[T]) WordTokenValues
func (m *Model[T]) WordTokenValues() []string
WordTokenValues returns the tokenized input text. This does not include delimiter tokens.
func (*Model[T]) WordTokens
func (m *Model[T]) WordTokens() []input.Token
WordTokens returns the tokenized input. This does not include delimiter tokens.
func (*Model[T]) WordTokensBeforeCursor
func (m *Model[T]) WordTokensBeforeCursor() []input.Token
WordTokensBeforeCursor returns the tokenized input up to the cursor position. This does not include delimiter tokens.
type Option
type Option[T any] func(settings *settings[T])
func WithCursorMode
func WithCursorMode[T any](cursorMode cursor.Mode) Option[T]
Example
package main
import (
"github.com/aschey/bubbleprompt/input/simpleinput"
"github.com/charmbracelet/bubbles/cursor"
)
func main() {
simpleinput.New(simpleinput.WithCursorMode[any](cursor.CursorStatic))
}
func WithDelimiterRegex
func WithDelimiterRegex[T any](delimiterRegex string) Option[T]
Example
package main
import (
"github.com/aschey/bubbleprompt/input/simpleinput"
)
func main() {
// Use period-delimited tokens instead of whitespace-delimited tokens
// If you change the delimiter regex, you'll probably also need to change the token regex
simpleinput.New(
simpleinput.WithTokenRegex[any](`[^\s\.]+`),
simpleinput.WithDelimiterRegex[any](`\s*\.\s*`),
)
}
func WithFormatter
func WithFormatter[T any](formatterFunc func(lexer parser.Lexer) parser.Formatter) Option[T]
Example
package main
import (
"github.com/aschey/bubbleprompt/input"
"github.com/aschey/bubbleprompt/input/simpleinput"
"github.com/aschey/bubbleprompt/parser"
"github.com/charmbracelet/lipgloss"
)
type alternatingFormatter struct {
lexer parser.Lexer
evenTextStyle lipgloss.Style
oddTextStyle lipgloss.Style
}
func (f alternatingFormatter) Lex(
input string,
_selectedToken *input.Token,
) ([]parser.FormatterToken, error) {
tokens, err := f.lexer.Lex(input)
if err != nil {
return nil, err
}
formatterTokens := []parser.FormatterToken{}
for i, token := range tokens {
formatterToken := parser.FormatterToken{Value: token.Value}
if i%2 == 0 {
formatterToken.Style = f.evenTextStyle
} else {
formatterToken.Style = f.oddTextStyle
}
formatterTokens = append(formatterTokens, formatterToken)
}
return formatterTokens, nil
}
func main() {
simpleinput.New(simpleinput.WithFormatter[any](func(lexer parser.Lexer) parser.Formatter {
return alternatingFormatter{
lexer: lexer,
evenTextStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("1")),
oddTextStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("2")),
}
}))
}
func WithPrompt
func WithPrompt[T any](prompt string) Option[T]
func WithSelectedTextStyle
func WithSelectedTextStyle[T any](style lipgloss.Style) Option[T]
Example
package main
import (
"github.com/aschey/bubbleprompt/input/simpleinput"
"github.com/charmbracelet/lipgloss"
)
func main() {
style := lipgloss.NewStyle().Foreground(lipgloss.Color("1")).Bold(true)
simpleinput.New(simpleinput.WithSelectedTextStyle[any](style))
}
func WithTokenRegex
func WithTokenRegex[T any](tokenRegex string) Option[T]
Example
package main
import (
"github.com/aschey/bubbleprompt/input/simpleinput"
)
func main() {
// Use period-delimited tokens instead of whitespace-delimited tokens
// If you change the token regex, you'll probably also need to change the delimiter regex
simpleinput.New(
simpleinput.WithTokenRegex[any](`[^\s\.]+`),
simpleinput.WithDelimiterRegex[any](`\s*\.\s*`),
)
}
Generated by gomarkdoc