Skip to main content

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

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