1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
package queryinput
import (
"container/list"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/noahgorstein/jqp/tui/theme"
)
type Bubble struct {
Styles Styles
textinput textinput.Model
history *list.List
historyMaxLen int
historySelected *list.Element
}
func New(jqtheme theme.Theme) Bubble {
s := DefaultStyles()
s.containerStyle.BorderForeground(jqtheme.Primary)
ti := textinput.New()
ti.Focus()
ti.PromptStyle.Height(1)
ti.TextStyle.Height(1)
ti.Prompt = lipgloss.NewStyle().Bold(true).Foreground(jqtheme.Secondary).Render("jq > ")
return Bubble{
Styles: s,
textinput: ti,
history: list.New(),
historyMaxLen: 512,
}
}
func (b *Bubble) SetBorderColor(color lipgloss.TerminalColor) {
b.Styles.containerStyle = b.Styles.containerStyle.BorderForeground(color)
}
func (b Bubble) GetInputValue() string {
return b.textinput.Value()
}
func (b *Bubble) RotateHistory() {
b.history.PushFront(b.textinput.Value())
b.historySelected = b.history.Front()
if b.history.Len() > b.historyMaxLen {
b.history.Remove(b.history.Back())
}
}
func (Bubble) Init() tea.Cmd {
return textinput.Blink
}
func (b *Bubble) SetWidth(width int) {
b.Styles.containerStyle = b.Styles.containerStyle.Width(width - b.Styles.containerStyle.GetHorizontalFrameSize())
b.textinput.Width = width - b.Styles.containerStyle.GetHorizontalFrameSize() - 1
}
func (b Bubble) View() string {
return b.Styles.containerStyle.Render(b.textinput.View())
}
func (b Bubble) Update(msg tea.Msg) (Bubble, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
return b.updateKeyMsg(msg)
default:
var cmd tea.Cmd
b.textinput, cmd = b.textinput.Update(msg)
return b, cmd
}
}
func (b *Bubble) SetQuery(query string) {
b.textinput.SetValue(query)
}
func (b Bubble) updateKeyMsg(msg tea.KeyMsg) (Bubble, tea.Cmd) {
switch msg.Type {
case tea.KeyUp:
return b.handleKeyUp()
case tea.KeyDown:
return b.handleKeyDown()
case tea.KeyEnter:
b.RotateHistory()
return b, nil
default:
var cmd tea.Cmd
b.textinput, cmd = b.textinput.Update(msg)
return b, cmd
}
}
func (b Bubble) handleKeyUp() (Bubble, tea.Cmd) {
if b.history.Len() == 0 {
return b, nil
}
n := b.historySelected.Next()
if n != nil {
b.textinput.SetValue(n.Value.(string))
b.textinput.CursorEnd()
b.historySelected = n
}
return b, nil
}
func (b Bubble) handleKeyDown() (Bubble, tea.Cmd) {
if b.history.Len() == 0 {
return b, nil
}
p := b.historySelected.Prev()
if p != nil {
b.textinput.SetValue(p.Value.(string))
b.textinput.CursorEnd()
b.historySelected = p
}
return b, nil
}
|