feat: multiline input with auto-expanding textarea

Switch from textinput to textarea bubble:
- Enter submits message
- Shift+Enter / Ctrl+J inserts newline
- Input area auto-expands from 1 to 10 lines based on content
- Line numbers hidden, prompt preserved
This commit is contained in:
2026-04-03 18:11:34 +02:00
parent f6f69cf8e5
commit fdf23ed4b7
2 changed files with 28 additions and 5 deletions

2
go.sum
View File

@@ -13,6 +13,8 @@ cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJ
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/VikingOwl91/mistral-go-sdk v1.2.1 h1:6OQMtOzJUFcvFUEtbX9VlglUPBn+dKOrQPnyoVKlpkA=
github.com/VikingOwl91/mistral-go-sdk v1.2.1/go.mod h1:f4emNtHUx2zSqY3V0LBz6lNI1jE6q/zh+SEU+/hJ0i4=
github.com/anthropics/anthropic-sdk-go v1.29.0 h1:7h1ZyRflhtxyuFkdwkVuJ1LdFAYdmizvgg0gd1uvOfI=

View File

@@ -8,7 +8,8 @@ import (
"strings"
tea "charm.land/bubbletea/v2"
"charm.land/bubbles/v2/textinput"
"charm.land/bubbles/v2/textarea"
"charm.land/bubbles/v2/key"
"charm.land/lipgloss/v2"
"somegit.dev/Owlibou/gnoma/internal/engine"
"somegit.dev/Owlibou/gnoma/internal/message"
@@ -51,7 +52,7 @@ type Model struct {
streamBuf strings.Builder
currentRole string
input textinput.Model
input textarea.Model
cwd string
gitBranch string
scrollOffset int
@@ -61,11 +62,21 @@ type Model struct {
}
func New(sess session.Session, cfg Config) Model {
ti := textinput.New()
ti.Placeholder = ""
ti := textarea.New()
ti.Placeholder = "Type a message... (Enter to send, Shift+Enter for newline)"
ti.Prompt = " "
ti.Focus()
ti.ShowLineNumbers = false
ti.SetHeight(1)
ti.MaxHeight = 10
ti.SetWidth(80)
ti.CharLimit = 0
// Remap: Shift+Enter/Ctrl+J for newline (not plain Enter)
km := ti.KeyMap
km.InsertNewline = key.NewBinding(key.WithKeys("shift+enter", "ctrl+j"))
ti.KeyMap = km
ti.Focus()
cwd, _ := os.Getwd()
gitBranch := detectGitBranch()
@@ -451,6 +462,16 @@ func (m Model) View() tea.View {
return tea.NewView("")
}
// Auto-size textarea based on content
lines := strings.Count(m.input.Value(), "\n") + 1
if lines < 1 {
lines = 1
}
if lines > 10 {
lines = 10
}
m.input.SetHeight(lines)
status := m.renderStatus()
input := m.renderInput()
topLine, bottomLine := m.renderSeparators()