mirror of
https://github.com/charmbracelet/gum.git
synced 2024-08-17 02:00:46 +03:00
feat: filter height and scrolling viewport
This commit is contained in:
parent
fb4a9e6320
commit
c049d1a5fa
@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/alecthomas/kong"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
"github.com/charmbracelet/bubbles/viewport"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/gum/internal/exit"
|
||||
"github.com/charmbracelet/gum/internal/files"
|
||||
@ -25,6 +26,8 @@ func (o Options) Run() error {
|
||||
i.Placeholder = o.Placeholder
|
||||
i.Width = o.Width
|
||||
|
||||
v := viewport.New(o.Width, o.Height)
|
||||
|
||||
var choices []string
|
||||
if input, _ := stdin.Read(); input != "" {
|
||||
choices = strings.Split(strings.TrimSpace(input), "\n")
|
||||
@ -37,9 +40,11 @@ func (o Options) Run() error {
|
||||
indicator: o.Indicator,
|
||||
matches: matchAll(choices),
|
||||
textinput: i,
|
||||
viewport: &v,
|
||||
indicatorStyle: o.IndicatorStyle.ToLipgloss(),
|
||||
matchStyle: o.MatchStyle.ToLipgloss(),
|
||||
textStyle: o.TextStyle.ToLipgloss(),
|
||||
height: o.Height,
|
||||
}, tea.WithOutput(os.Stderr))
|
||||
|
||||
tm, err := p.StartReturningModel()
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
"github.com/charmbracelet/bubbles/viewport"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/mattn/go-runewidth"
|
||||
@ -23,6 +24,7 @@ import (
|
||||
|
||||
type model struct {
|
||||
textinput textinput.Model
|
||||
viewport *viewport.Model
|
||||
choices []string
|
||||
matches []fuzzy.Match
|
||||
selected int
|
||||
@ -78,29 +80,38 @@ func (m model) View() string {
|
||||
s.WriteRune('\n')
|
||||
}
|
||||
|
||||
tv := m.textinput.View()
|
||||
results := lipgloss.NewStyle().MaxHeight(m.height - lipgloss.Height(tv)).Render(s.String())
|
||||
m.viewport.SetContent(s.String())
|
||||
|
||||
// View the input and the filtered choices
|
||||
return tv + "\n" + results
|
||||
return m.textinput.View() + "\n" + m.viewport.View()
|
||||
}
|
||||
|
||||
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
var cmd tea.Cmd
|
||||
switch msg := msg.(type) {
|
||||
case tea.WindowSizeMsg:
|
||||
m.height = msg.Height
|
||||
if m.height == 0 || m.height > msg.Height {
|
||||
m.viewport.Height = msg.Height - lipgloss.Height(m.textinput.View())
|
||||
}
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "ctrl+c", "esc":
|
||||
m.aborted = true
|
||||
fallthrough
|
||||
m.quitting = true
|
||||
return m, tea.Quit
|
||||
case "enter":
|
||||
m.quitting = true
|
||||
return m, tea.Quit
|
||||
case "ctrl+n", "ctrl+j", "down":
|
||||
m.selected = clamp(0, len(m.matches)-1, m.selected+1)
|
||||
if m.selected >= m.viewport.YOffset+m.viewport.Height {
|
||||
m.viewport.LineDown(1)
|
||||
}
|
||||
case "ctrl+p", "ctrl+k", "up":
|
||||
m.selected = clamp(0, len(m.matches)-1, m.selected-1)
|
||||
if m.selected < m.viewport.YOffset {
|
||||
m.viewport.SetYOffset(m.selected)
|
||||
}
|
||||
default:
|
||||
m.textinput, cmd = m.textinput.Update(msg)
|
||||
|
||||
|
@ -13,4 +13,5 @@ type Options struct {
|
||||
Prompt string `help:"Prompt to display" default:"> "`
|
||||
PromptStyle style.Styles `embed:"" prefix:"prompt." set:"defaultForeground=240" set:"name=prompt"`
|
||||
Width int `help:"Input width" default:"20"`
|
||||
Height int `help:"Input height" default:"0"`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user